package com.smedi.ismedi.inmail.core.application.query.impl;

import com.aliyun.tea.TeaException;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smedi.ismedi.authority.starter.util.AuthorityUtil;
import com.smedi.ismedi.constructionproject.api.dto.response.resp.ProjectAssignmentResp;
import com.smedi.ismedi.constructionproject.api.dto.response.resp.ProjectResp;
import com.smedi.ismedi.constructionproject.api.dto.response.resp.ProjectWithDingResp;
import com.smedi.ismedi.inmail.api.dto.request.DingDingProjectRequest;
import com.smedi.ismedi.inmail.core.application.command.*;
import com.smedi.ismedi.inmail.core.application.query.OverviewQueryService;
import com.smedi.ismedi.inmail.core.application.query.vo.*;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.DingDeptUser;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.VideoMonitor;
import com.smedi.ismedi.inmail.core.domain.dto.*;
import com.smedi.ismedi.inmail.core.domain.repository.DingAttendanceResultRepository;
import com.smedi.ismedi.inmail.core.domain.repository.DingDeptUserRepository;
import com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField;
import com.smedi.ismedi.inmail.core.infrastructure.constant.DingDing;
import com.smedi.ismedi.inmail.core.infrastructure.constant.ProjectTypeEnum;
import com.smedi.ismedi.inmail.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.model.DingAttendanceResultEntity;
import com.smedi.ismedi.inmail.core.port.adapter.service.*;
import com.smedi.ismedi.organization.api.dto.response.resp.AllOrganizationResp;
import com.smedi.ismedi.organization.api.dto.response.resp.OrganizationResp;
import com.smedi.ismedi.personnel.api.dto.response.resp.PersonResp;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.ACCESS_HR_ORGANIZATION;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.ACCESS_PROJECT;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.EpcTypeEnum.*;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.MonitorOnlineStatusEnum.*;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.MonitorTypeEnum.DEFAULT_TYPE;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.MonitorTypeEnum.NOT_INSTALLED;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.OrganizationTypeEnum.PROJECT_MANAGEMENT_ORGANIZATION;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.ProjectStatusEnum.*;
import static com.smedi.ismedi.web.starter.thread.ThreadPool.IO_INSTANCE;

/**
 * 查询服务实现类
 *
 * @author jiangqinxuan
 * @date 2021/07/30
 */
@Service
@AllArgsConstructor
@Slf4j
public class OverviewQueryServiceImpl implements OverviewQueryService {
    private final ProjectRemoteService projectRemoteService;
    private final OrganizationRemoteService organizationRemoteService;
    private final AuthorityUtil authorityUtil;
    private final AdapterConverter adapterConverter;
    private final SafetyCheckRemoteApi safetyCheckRemoteApi;
    private final VideoMonitorRemoteApi videoMonitorRemoteApi;
    private final HiddenDangerRemoteApi hiddenDangerRemoteApi;
    private final PersonRemoteApi personRemoteApi;
    private final ProjectAssignmentRemoteApiService projectAssignmentRemoteApiService;

    private final DingDeptUserRepository dingDeptUserRepository;

    private final DingAttendanceResultRepository attendanceResultRepository;

    private static final List<String> jobs = Arrays.asList("EPC项目经理"
            , "施工项目经理", "设计专业负责人", "技术负责人", "设计经理", "费控经理", "施工员", "安全员"
            , "质量员", "标准员", "材料员", "机械员", "劳务员", "资料员");

    @Override
    public ProjectOverviewPageVo getProjectOverviewPage(ProjectOverviewPageCommand projectOverviewPageCommand) {
        List<ProjectOverviewVo> records = new ArrayList<>();
        BigDecimal contractNum = new BigDecimal("0");
        BigDecimal totalNum = new BigDecimal("0");
        BigDecimal notStartedNum = new BigDecimal("0");
        BigDecimal constructingNum = new BigDecimal("0");
        BigDecimal stoppedNum = new BigDecimal("0");
        BigDecimal finishedNum = new BigDecimal("0");
        BigDecimal completedNum = new BigDecimal("0");
        BigDecimal selfSupportNum = new BigDecimal("0");
        BigDecimal consortiumNum = new BigDecimal("0");
        BigDecimal selfSupportConsortiumNum = new BigDecimal("0");

        long offset = (projectOverviewPageCommand.getCurrent() - 1) * projectOverviewPageCommand.getSize();
        long limit = projectOverviewPageCommand.getCurrent() * projectOverviewPageCommand.getSize();

        List<ProjectOverviewVo> projectOverviews = this.getProjectOverviewList(adapterConverter.projectOverviewPageCommandToProjectOverviewListCommand(projectOverviewPageCommand));

        for (int i = 0; i < projectOverviews.size(); i++) {

            ProjectOverviewVo projectOverviewVo = projectOverviews.get(i);

            contractNum = contractNum.add(projectOverviewVo.getContractNum());
            totalNum = totalNum.add(projectOverviewVo.getTotalNum());
            notStartedNum = notStartedNum.add(projectOverviewVo.getNotStartedNum());
            constructingNum = constructingNum.add(projectOverviewVo.getConstructingNum());
            stoppedNum = stoppedNum.add(projectOverviewVo.getStoppedNum());
            finishedNum = finishedNum.add(projectOverviewVo.getFinishedNum());
            completedNum = completedNum.add(projectOverviewVo.getCompletedNum());
            selfSupportNum = selfSupportNum.add(projectOverviewVo.getSelfSupportNum());
            consortiumNum = consortiumNum.add(projectOverviewVo.getConsortiumNum());
            selfSupportConsortiumNum = selfSupportConsortiumNum.add(projectOverviewVo.getSelfSupportConsortiumNum());

            if (i >= offset && i < limit) {
                records.add(projectOverviewVo);
            }
        }

        ProjectOverviewPageVo projectOverviewPageVo = ProjectOverviewPageVo.builder()
                .totalNum(totalNum)
                .contractNum(contractNum)
                .notStartedNum(notStartedNum)
                .constructingNum(constructingNum)
                .stoppedNum(stoppedNum)
                .finishedNum(finishedNum)
                .completedNum(completedNum)
                .selfSupportNum(selfSupportNum)
                .consortiumNum(consortiumNum)
                .selfSupportConsortiumNum(selfSupportConsortiumNum)
                .build();

        projectOverviewPageVo.setRecords(records);
        projectOverviewPageVo.setTotal(projectOverviews.size());
        projectOverviewPageVo.setCurrent((int) projectOverviewPageCommand.getCurrent());
        projectOverviewPageVo.setSize((int) projectOverviewPageCommand.getSize());

        return projectOverviewPageVo;
    }

    @Override
    public List<ProjectOverviewVo> getProjectOverviewList(ProjectOverviewListCommand projectOverviewListCommand) {
        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());

        List<ProjectOverviewVo> projectOverviewVos = new ArrayList<>();

        List<OrganizationResp> organizations = organizationRemoteService.getOrganizationList(OrganizationQuery.builder().build());
        List<OrganizationResp> organizationsSorted = organizations.stream().filter(organizationResp -> organizationIds.contains(organizationResp.getId())).filter(organizationResp -> organizationResp.getType().equals(PROJECT_MANAGEMENT_ORGANIZATION.name())).sorted(Comparator.comparing(OrganizationResp::getDisplayOrder)).collect(Collectors.toList());

        List<ProjectResp> projects = projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build());
        Map<Long, List<ProjectResp>> organizationIdProjectMap = new HashMap<>();
        LocalDate now = LocalDate.now();
        for (ProjectResp projectResp : projects) {
            List<ProjectResp> projectsByOrganizationId = organizationIdProjectMap.getOrDefault(projectResp.getHrOrganizationId(), new ArrayList<>());
            projectsByOrganizationId.add(projectResp);
            organizationIdProjectMap.put(projectResp.getHrOrganizationId(), projectsByOrganizationId);
        }

        for (OrganizationResp organizationResp : organizationsSorted) {
            ProjectOverviewVo projectOverviewVo = new ProjectOverviewVo();
            projectOverviewVo.setName(organizationResp.getShortName());
            projectOverviewVo.setFullName(organizationResp.getFullName());

            BigDecimal totalNum = new BigDecimal("0");
            BigDecimal contractNum = new BigDecimal("0");
            BigDecimal notStartedNum = new BigDecimal("0");
            BigDecimal constructingNum = new BigDecimal("0");
            BigDecimal stoppedNum = new BigDecimal("0");
            BigDecimal finishedNum = new BigDecimal("0");
            BigDecimal completedNum = new BigDecimal("0");
            BigDecimal selfSupportNum = new BigDecimal("0");
            BigDecimal consortiumNum = new BigDecimal("0");
            BigDecimal selfSupportConsortiumNum = new BigDecimal("0");

            // 统计数据
            List<ProjectResp> projectsByOrganizationId = organizationIdProjectMap.getOrDefault(organizationResp.getId(), new ArrayList<>());
            for (ProjectResp projectResp : projectsByOrganizationId) {
                contractNum = contractNum.add(projectResp.getContractNum());
                totalNum = totalNum.add(new BigDecimal("1"));
                if (projectResp.getProjectStatus().equals(NOT_STARTED.name())) {
                    notStartedNum = notStartedNum.add(new BigDecimal("1"));
                }
                if (projectResp.getProjectStatus().equals(CONSTRUCTING.name())) {
                    constructingNum = constructingNum.add(new BigDecimal("1"));
                }
                if (projectResp.getProjectStatus().equals(STOPPED.name())) {
                    stoppedNum = stoppedNum.add(new BigDecimal("1"));
                }
                if (projectResp.getProjectStatus().equals(FINISHED.name())) {
                    if (projectResp.getFinishDate() != null) {
                        long year = projectResp.getFinishDate().until(now, ChronoUnit.DAYS);
                        if (year <= 365) {
                            finishedNum = finishedNum.add(new BigDecimal("1"));
                        }
                    }
                }
                if (projectResp.getProjectStatus().equals(COMPLETED.name())) {
                    if (projectResp.getFinishDate() != null) {
                        long year = projectResp.getFinishDate().until(now, ChronoUnit.DAYS);
                        if (year <= 730) {
                            completedNum = completedNum.add(new BigDecimal("1"));
                        }
                    }
                }
                if (projectResp.getEpcType().equals(SELF_SUPPORT.name())) {
                    selfSupportNum = selfSupportNum.add(new BigDecimal("1"));
                }
                if (projectResp.getEpcType().equals(CONSORTIUM.name())) {
                    consortiumNum = consortiumNum.add(new BigDecimal("1"));
                }
                if (projectResp.getEpcType().equals(SELF_SUPPORT_CONSORTIUM.name())) {
                    selfSupportConsortiumNum = selfSupportConsortiumNum.add(new BigDecimal("1"));
                }
            }

            projectOverviewVo.setContractNum(contractNum);
            projectOverviewVo.setTotalNum(totalNum);
            projectOverviewVo.setNotStartedNum(notStartedNum);
            projectOverviewVo.setConstructingNum(constructingNum);
            projectOverviewVo.setStoppedNum(stoppedNum);
            projectOverviewVo.setFinishedNum(finishedNum);
            projectOverviewVo.setCompletedNum(completedNum);
            projectOverviewVo.setStoppedNum(stoppedNum);
            projectOverviewVo.setSelfSupportNum(selfSupportNum);
            projectOverviewVo.setConsortiumNum(consortiumNum);
            projectOverviewVo.setSelfSupportConsortiumNum(selfSupportConsortiumNum);

            projectOverviewVos.add(projectOverviewVo);
        }

        if (null != projectOverviewListCommand.getOrderBy()) {
            if (projectOverviewListCommand.getOrderBy().equals("totalNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getTotalNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getTotalNum).reversed()).collect(Collectors.toList());
                }
            }
            if (projectOverviewListCommand.getOrderBy().equals("notStartedNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getNotStartedNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getNotStartedNum).reversed()).collect(Collectors.toList());
                }
            }
            if (projectOverviewListCommand.getOrderBy().equals("constructingNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getConstructingNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getConstructingNum).reversed()).collect(Collectors.toList());
                }
            }
            if (projectOverviewListCommand.getOrderBy().equals("stoppedNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getStoppedNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getStoppedNum).reversed()).collect(Collectors.toList());
                }
            }
            if (projectOverviewListCommand.getOrderBy().equals("finishedNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getFinishedNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getFinishedNum).reversed()).collect(Collectors.toList());
                }
            }
            if (projectOverviewListCommand.getOrderBy().equals("completedNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getCompletedNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getCompletedNum).reversed()).collect(Collectors.toList());
                }
            }
            if (projectOverviewListCommand.getOrderBy().equals("selfSupportNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getSelfSupportNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getSelfSupportNum).reversed()).collect(Collectors.toList());
                }
            }
            if (projectOverviewListCommand.getOrderBy().equals("consortiumNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getConsortiumNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getConsortiumNum).reversed()).collect(Collectors.toList());
                }
            }
            if (projectOverviewListCommand.getOrderBy().equals("selfSupportConsortiumNum")) {
                if (projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getSelfSupportConsortiumNum)).collect(Collectors.toList());
                }
                if (!projectOverviewListCommand.getAsc()) {
                    projectOverviewVos = projectOverviewVos.stream().sorted(Comparator.comparing(ProjectOverviewVo::getSelfSupportConsortiumNum).reversed()).collect(Collectors.toList());
                }
            }
        }

        return projectOverviewVos;
    }

    @Override
    public SafetyCheckOrgOverviewPageVo getSafetyCheckOrganizationOverviewPage(SafetyCheckOrganizationOverviewPageCommand safetyCheckOrganizationOverviewPageCommand) {

        List<SafetyCheckOrganizationOverviewVo> records = new ArrayList<>();

        BigDecimal totalNum = new BigDecimal("0");
        BigDecimal checkProjectNum = new BigDecimal("0");
        BigDecimal hiddenDangerProjectNum = new BigDecimal("0");
        BigDecimal hiddenDangerRectificationProjectNum = new BigDecimal("0");
        BigDecimal checkMajorNum = new BigDecimal("0");
        BigDecimal hiddenDangerMajorNum = new BigDecimal("0");
        BigDecimal hiddenDangerRectificationMajorNum = new BigDecimal("0");
        BigDecimal checkLeaderNum = new BigDecimal("0");
        BigDecimal hiddenDangerLeaderNum = new BigDecimal("0");
        BigDecimal hiddenDangerRectificationLeaderNum = new BigDecimal("0");
        BigDecimal hiddenDangerNum = new BigDecimal("0");
        BigDecimal hiddenDangerRectificationNum = new BigDecimal("0");

        long offset = (safetyCheckOrganizationOverviewPageCommand.getCurrent() - 1) * safetyCheckOrganizationOverviewPageCommand.getSize();
        long limit = safetyCheckOrganizationOverviewPageCommand.getCurrent() * safetyCheckOrganizationOverviewPageCommand.getSize();

        List<SafetyCheckOrganizationOverviewVo> safetyCheckOrganizationOverviewVos = this.getSafetyCheckOrganizationOverviewList(adapterConverter.safetyCheckOrganizationOverviewPageCommandToSafetyCheckOrganizationOverviewListCommand(safetyCheckOrganizationOverviewPageCommand));

        for (int i = 0; i < safetyCheckOrganizationOverviewVos.size(); i++) {

            SafetyCheckOrganizationOverviewVo safetyCheckOrganizationOverviewVo = safetyCheckOrganizationOverviewVos.get(i);
            totalNum = totalNum.add(safetyCheckOrganizationOverviewVo.getTotalNum());
            checkProjectNum = checkProjectNum.add(safetyCheckOrganizationOverviewVo.getCheckProjectNum());
            hiddenDangerProjectNum = hiddenDangerProjectNum.add(safetyCheckOrganizationOverviewVo.getHiddenDangerProjectNum());
            hiddenDangerRectificationProjectNum = hiddenDangerRectificationProjectNum.add(safetyCheckOrganizationOverviewVo.getHiddenDangerRectificationProjectNum());
            checkMajorNum = checkMajorNum.add(safetyCheckOrganizationOverviewVo.getCheckMajorNum());
            hiddenDangerMajorNum = hiddenDangerMajorNum.add(safetyCheckOrganizationOverviewVo.getHiddenDangerMajorNum());
            hiddenDangerRectificationMajorNum = hiddenDangerRectificationMajorNum.add(safetyCheckOrganizationOverviewVo.getHiddenDangerRectificationMajorNum());
            checkLeaderNum = checkLeaderNum.add(safetyCheckOrganizationOverviewVo.getCheckLeaderNum());
            hiddenDangerLeaderNum = hiddenDangerLeaderNum.add(safetyCheckOrganizationOverviewVo.getHiddenDangerLeaderNum());
            hiddenDangerRectificationLeaderNum = hiddenDangerRectificationLeaderNum.add(safetyCheckOrganizationOverviewVo.getHiddenDangerRectificationLeaderNum());
            hiddenDangerNum = hiddenDangerNum.add(safetyCheckOrganizationOverviewVo.getHiddenDangerNum());
            hiddenDangerRectificationNum = hiddenDangerRectificationNum.add(safetyCheckOrganizationOverviewVo.getHiddenDangerRectificationNum());

            if (i >= offset && i < limit) {
                records.add(safetyCheckOrganizationOverviewVo);
            }
        }

        SafetyCheckOrgOverviewPageVo safetyCheckOrgOverviewPageVo = SafetyCheckOrgOverviewPageVo.builder()
                .totalNum(totalNum)
                .checkProjectNum(checkProjectNum)
                .hiddenDangerProjectNum(hiddenDangerProjectNum)
                .hiddenDangerRectificationProjectNum(hiddenDangerRectificationProjectNum)
                .checkMajorNum(checkMajorNum)
                .hiddenDangerMajorNum(hiddenDangerMajorNum)
                .hiddenDangerRectificationMajorNum(hiddenDangerRectificationMajorNum)
                .checkLeaderNum(checkLeaderNum)
                .hiddenDangerLeaderNum(hiddenDangerLeaderNum)
                .hiddenDangerRectificationLeaderNum(hiddenDangerRectificationLeaderNum)
                .hiddenDangerNum(hiddenDangerNum)
                .hiddenDangerRectificationNum(hiddenDangerRectificationNum)
                .build();

        safetyCheckOrgOverviewPageVo.setCurrent((int) safetyCheckOrganizationOverviewPageCommand.getCurrent());
        safetyCheckOrgOverviewPageVo.setSize((int) safetyCheckOrganizationOverviewPageCommand.getSize());
        safetyCheckOrgOverviewPageVo.setRecords(records);
        safetyCheckOrgOverviewPageVo.setTotal(safetyCheckOrganizationOverviewVos.size());

        return safetyCheckOrgOverviewPageVo;
    }

    @Override
    public List<SafetyCheckOrganizationOverviewVo> getSafetyCheckOrganizationOverviewList(SafetyCheckOrganizationOverviewListCommand safetyCheckOrganizationOverviewListCommand) {
        List<SafetyCheckOrganizationOverviewVo> safetyCheckOrganizationOverviewVos;
        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return new ArrayList<>();
        }

        AtomicReference<List<OrganizationResp>> allOrganizations = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<SafetyCheckVo>> allSafetyChecks = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<HiddenDangerVo>> allHiddenDangers = new AtomicReference<>(new ArrayList<>());

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allOrganizations.set(organizationRemoteService.getOrganizationList(OrganizationQuery.builder().ids(organizationIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allSafetyChecks.set(safetyCheckRemoteApi.getSafetyCheckList(SafetyCheckQuery.builder()
                        .submitted(true)
                        .checkStartDateTime(safetyCheckOrganizationOverviewListCommand.getStartDateTime())
                        .checkEndDateTime(safetyCheckOrganizationOverviewListCommand.getEndDateTime())
                        .build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allHiddenDangers.set(hiddenDangerRemoteApi.getHiddenDangerList(HiddenDangerQuery.builder()
                        .submitted(true)
                        .checkStartDateTime(safetyCheckOrganizationOverviewListCommand.getStartDateTime())
                        .checkEndDateTime(safetyCheckOrganizationOverviewListCommand.getEndDateTime())
                        .build())), IO_INSTANCE)
        ).join();

        Map<Long, Long> projectIdOrganizationIdMap = new HashMap<>();
        for (ProjectResp projectResp : allProjects.get()) {
            projectIdOrganizationIdMap.put(projectResp.getId(), projectResp.getHrOrganizationId());
        }

        Map<Long, OrganizationResp> organizationIdOrganizationMap = new HashMap<>();
        for (OrganizationResp organizationResp : allOrganizations.get()) {
            organizationIdOrganizationMap.put(organizationResp.getId(), organizationResp);
        }

        Map<Long, List<SafetyCheckVo>> projectIdSafetyChecksMap = new HashMap<>();
        for (SafetyCheckVo safetyCheckVo : allSafetyChecks.get()) {
            List<SafetyCheckVo> safetyChecksByProjectIdVo = projectIdSafetyChecksMap.getOrDefault(safetyCheckVo.getProjectId(), new ArrayList<>());
            safetyChecksByProjectIdVo.add(safetyCheckVo);
            projectIdSafetyChecksMap.put(safetyCheckVo.getProjectId(), safetyChecksByProjectIdVo);
        }

        Map<Long, List<HiddenDangerVo>> projectIdHiddenDangersMap = new HashMap<>();
        for (HiddenDangerVo hiddenDangerVo : allHiddenDangers.get()) {
            List<HiddenDangerVo> hiddenDangersByProjectIdVo = projectIdHiddenDangersMap.getOrDefault(hiddenDangerVo.getProjectId(), new ArrayList<>());
            hiddenDangersByProjectIdVo.add(hiddenDangerVo);
            projectIdHiddenDangersMap.put(hiddenDangerVo.getProjectId(), hiddenDangersByProjectIdVo);
        }

        Map<Long, String> safetyCheckIdSafetyCheckQualityMap = allSafetyChecks.get().stream().collect(Collectors.toMap(SafetyCheckVo::getId, SafetyCheckVo::getSafetyCheckQuality));

        Map<Long, SafetyCheckOrganizationOverviewVo> organizationIdResultMap = new HashMap<>();
        for (ProjectResp projectResp : allProjects.get()) {
            if (!projectResp.getProjectStatus().equals(CONSTRUCTING.name())) {
                continue;
            }
            Long projectId = projectResp.getId();
            Long organizationId = projectIdOrganizationIdMap.get(projectId);
            OrganizationResp organization = organizationIdOrganizationMap.get(organizationId);
            if (null == organization) {
                continue;
            }
            SafetyCheckOrganizationOverviewVo safetyCheckOrganizationOverviewVo = organizationIdResultMap.getOrDefault(organizationId, SafetyCheckOrganizationOverviewVo.builder()
                    .totalNum(new BigDecimal("0"))
                    .checkProjectNum(new BigDecimal("0"))
                    .hiddenDangerProjectNum(new BigDecimal("0"))
                    .hiddenDangerRectificationProjectNum(new BigDecimal("0"))
                    .checkMajorNum(new BigDecimal("0"))
                    .hiddenDangerMajorNum(new BigDecimal("0"))
                    .hiddenDangerRectificationMajorNum(new BigDecimal("0"))
                    .checkLeaderNum(new BigDecimal("0"))
                    .hiddenDangerLeaderNum(new BigDecimal("0"))
                    .hiddenDangerRectificationLeaderNum(new BigDecimal("0"))
                    .hiddenDangerNum(new BigDecimal("0"))
                    .hiddenDangerRectificationNum(new BigDecimal("0"))
                    .name(organization.getShortName())
                    .fullName(organization.getFullName())
                    .organizationDisplayOrder(organization.getDisplayOrder())
                    .build());

            BigDecimal totalNum = safetyCheckOrganizationOverviewVo.getTotalNum();
            BigDecimal checkProjectNum = safetyCheckOrganizationOverviewVo.getCheckProjectNum();
            BigDecimal hiddenDangerProjectNum = safetyCheckOrganizationOverviewVo.getHiddenDangerProjectNum();
            BigDecimal hiddenDangerRectificationProjectNum = safetyCheckOrganizationOverviewVo.getHiddenDangerRectificationProjectNum();
            BigDecimal checkMajorNum = safetyCheckOrganizationOverviewVo.getCheckMajorNum();
            BigDecimal hiddenDangerMajorNum = safetyCheckOrganizationOverviewVo.getHiddenDangerMajorNum();
            BigDecimal hiddenDangerRectificationMajorNum = safetyCheckOrganizationOverviewVo.getHiddenDangerRectificationMajorNum();
            BigDecimal checkLeaderNum = safetyCheckOrganizationOverviewVo.getCheckLeaderNum();
            BigDecimal hiddenDangerLeaderNum = safetyCheckOrganizationOverviewVo.getHiddenDangerLeaderNum();
            BigDecimal hiddenDangerRectificationLeaderNum = safetyCheckOrganizationOverviewVo.getHiddenDangerRectificationLeaderNum();
            BigDecimal hiddenDangerNum = safetyCheckOrganizationOverviewVo.getHiddenDangerNum();
            BigDecimal hiddenDangerRectificationNum = safetyCheckOrganizationOverviewVo.getHiddenDangerRectificationNum();

            // 统计安全检查数据
            List<SafetyCheckVo> safetyCheckVos = projectIdSafetyChecksMap.getOrDefault(projectId, new ArrayList<>());
            for (SafetyCheckVo safetyCheckVo : safetyCheckVos) {
                totalNum = totalNum.add(new BigDecimal("1"));
                if (safetyCheckVo.getSafetyCheckQuality().equals("项目部检查")) {
                    checkProjectNum = checkProjectNum.add(new BigDecimal("1"));
                }
                if (safetyCheckVo.getSafetyCheckQuality().equals("主体院检查")) {
                    checkMajorNum = checkMajorNum.add(new BigDecimal("1"));
                }
                if (safetyCheckVo.getSafetyCheckQuality().equals("总院检查")) {
                    checkLeaderNum = checkLeaderNum.add(new BigDecimal("1"));
                }
            }

            // 统计安全隐患数据
            List<HiddenDangerVo> hiddenDangerVos = projectIdHiddenDangersMap.getOrDefault(projectId, new ArrayList<>());
            for (HiddenDangerVo hiddenDangerVo : hiddenDangerVos) {
                //剔除不属于安全检查下的安全隐患
                if (hiddenDangerVo.getSafetyCheckId() == null) {
                    continue;
                }
                String hiddenDangerInSafetyCheckQuality = safetyCheckIdSafetyCheckQualityMap.get(hiddenDangerVo.getSafetyCheckId());
                //剔除没有检查性质的安全检查
                if (hiddenDangerInSafetyCheckQuality == null) {
                    continue;
                }
                hiddenDangerNum = hiddenDangerNum.add(new BigDecimal("1"));

                if (hiddenDangerInSafetyCheckQuality.equals("项目部检查")) {
                    hiddenDangerProjectNum = hiddenDangerProjectNum.add(new BigDecimal("1"));
                }
                if (hiddenDangerInSafetyCheckQuality.equals("主体院检查")) {
                    hiddenDangerMajorNum = hiddenDangerMajorNum.add(new BigDecimal("1"));
                }
                if (hiddenDangerInSafetyCheckQuality.equals("总院检查")) {
                    hiddenDangerLeaderNum = hiddenDangerLeaderNum.add(new BigDecimal("1"));
                }
                if (hiddenDangerVo.getHiddenDangerStatus().equals("已完成")) {
                    hiddenDangerRectificationNum = hiddenDangerRectificationNum.add(new BigDecimal("1"));
                    if (hiddenDangerInSafetyCheckQuality.equals("项目部检查")) {
                        hiddenDangerRectificationProjectNum = hiddenDangerRectificationProjectNum.add(new BigDecimal("1"));
                    }
                    if (hiddenDangerInSafetyCheckQuality.equals("主体院检查")) {
                        hiddenDangerRectificationMajorNum = hiddenDangerRectificationMajorNum.add(new BigDecimal("1"));
                    }
                    if (hiddenDangerInSafetyCheckQuality.equals("总院检查")) {
                        hiddenDangerRectificationLeaderNum = hiddenDangerRectificationLeaderNum.add(new BigDecimal("1"));
                    }
                }
            }

            safetyCheckOrganizationOverviewVo.setTotalNum(totalNum);
            safetyCheckOrganizationOverviewVo.setCheckProjectNum(checkProjectNum);
            safetyCheckOrganizationOverviewVo.setHiddenDangerProjectNum(hiddenDangerProjectNum);
            safetyCheckOrganizationOverviewVo.setHiddenDangerRectificationProjectNum(hiddenDangerRectificationProjectNum);
            safetyCheckOrganizationOverviewVo.setCheckMajorNum(checkMajorNum);
            safetyCheckOrganizationOverviewVo.setHiddenDangerMajorNum(hiddenDangerMajorNum);
            safetyCheckOrganizationOverviewVo.setHiddenDangerRectificationMajorNum(hiddenDangerRectificationMajorNum);
            safetyCheckOrganizationOverviewVo.setCheckLeaderNum(checkLeaderNum);
            safetyCheckOrganizationOverviewVo.setHiddenDangerLeaderNum(hiddenDangerLeaderNum);
            safetyCheckOrganizationOverviewVo.setHiddenDangerRectificationLeaderNum(hiddenDangerRectificationLeaderNum);
            safetyCheckOrganizationOverviewVo.setHiddenDangerNum(hiddenDangerNum);
            safetyCheckOrganizationOverviewVo.setHiddenDangerRectificationNum(hiddenDangerRectificationNum);

            if (hiddenDangerNum.compareTo(new BigDecimal("0")) == 0) {
                safetyCheckOrganizationOverviewVo.setRectificationRate(new BigDecimal("1"));
            }
            if (hiddenDangerProjectNum.compareTo(new BigDecimal("0")) == 0) {
                safetyCheckOrganizationOverviewVo.setRectificationProjectRate(new BigDecimal("1"));
            }
            if (hiddenDangerMajorNum.compareTo(new BigDecimal("0")) == 0) {
                safetyCheckOrganizationOverviewVo.setRectificationMajorRate(new BigDecimal("1"));
            }
            if (hiddenDangerLeaderNum.compareTo(new BigDecimal("0")) == 0) {
                safetyCheckOrganizationOverviewVo.setRectificationLeaderRate(new BigDecimal("1"));
            }

            if (hiddenDangerNum.compareTo(new BigDecimal("0")) != 0) {
                safetyCheckOrganizationOverviewVo.setRectificationRate(hiddenDangerRectificationNum.divide(hiddenDangerNum, 20, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP));
            }
            if (hiddenDangerProjectNum.compareTo(new BigDecimal("0")) != 0) {
                safetyCheckOrganizationOverviewVo.setRectificationProjectRate(hiddenDangerRectificationProjectNum.divide(hiddenDangerProjectNum, 20, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP));
            }
            if (hiddenDangerMajorNum.compareTo(new BigDecimal("0")) != 0) {
                safetyCheckOrganizationOverviewVo.setRectificationMajorRate(hiddenDangerRectificationMajorNum.divide(hiddenDangerMajorNum, 20, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP));
            }
            if (hiddenDangerLeaderNum.compareTo(new BigDecimal("0")) != 0) {
                safetyCheckOrganizationOverviewVo.setRectificationLeaderRate(hiddenDangerRectificationLeaderNum.divide(hiddenDangerLeaderNum, 20, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP));
            }
            organizationIdResultMap.put(organizationId, safetyCheckOrganizationOverviewVo);
        }

        if (organizationIdResultMap.values().isEmpty()) {
            return new ArrayList<>();
        }
        safetyCheckOrganizationOverviewVos = organizationIdResultMap.values().stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getOrganizationDisplayOrder)).collect(Collectors.toList());

        if (null != safetyCheckOrganizationOverviewListCommand.getOrderBy()) {
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("totalNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getTotalNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getTotalNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("checkProjectNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getCheckProjectNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getCheckProjectNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("hiddenDangerProjectNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerProjectNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerProjectNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("rectificationProjectRate")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getRectificationProjectRate)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getRectificationProjectRate).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("hiddenDangerRectificationProjectNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerRectificationProjectNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerRectificationProjectNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("checkMajorNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getCheckMajorNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getCheckMajorNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("hiddenDangerMajorNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerMajorNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerMajorNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("rectificationMajorRate")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getRectificationMajorRate)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getRectificationMajorRate).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("hiddenDangerRectificationMajorNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerRectificationMajorNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerRectificationMajorNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("checkLeaderNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getCheckLeaderNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getCheckLeaderNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("hiddenDangerLeaderNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerLeaderNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerLeaderNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("rectificationLeaderRate")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getRectificationLeaderRate)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getRectificationLeaderRate).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("hiddenDangerRectificationLeaderNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerRectificationLeaderNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerRectificationLeaderNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("hiddenDangerNum")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerNum)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getHiddenDangerNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckOrganizationOverviewListCommand.getOrderBy().equals("rectificationRate")) {
                if (safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getRectificationRate)).collect(Collectors.toList());
                }
                if (!safetyCheckOrganizationOverviewListCommand.getAsc()) {
                    safetyCheckOrganizationOverviewVos = safetyCheckOrganizationOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckOrganizationOverviewVo::getRectificationRate).reversed()).collect(Collectors.toList());
                }
            }

        }

        return safetyCheckOrganizationOverviewVos;
    }

    @Override
    public Page<SafetyCheckProjectOverviewVo> getSafetyCheckProjectOverviewPage(SafetyCheckProjectOverviewPageCommand safetyCheckProjectOverviewPageCommand) {
        Page<SafetyCheckProjectOverviewVo> safetyCheckOverviewPage = new Page<>(safetyCheckProjectOverviewPageCommand.getCurrent(), safetyCheckProjectOverviewPageCommand.getSize());
        List<SafetyCheckProjectOverviewVo> record = new ArrayList<>();

        long offset = (safetyCheckProjectOverviewPageCommand.getCurrent() - 1) * safetyCheckProjectOverviewPageCommand.getSize();
        long limit = safetyCheckProjectOverviewPageCommand.getCurrent() * safetyCheckProjectOverviewPageCommand.getSize();

        List<SafetyCheckProjectOverviewVo> safetyCheckProjectOverviewVos = this.getSafetyCheckProjectOverviewList(adapterConverter.safetyCheckProjectOverviewPageCommandToSafetyCheckProjectOverviewListCommand(safetyCheckProjectOverviewPageCommand));

        for (int i = (int) offset; i < limit; i++) {
            if (i >= safetyCheckProjectOverviewVos.size()) {
                continue;
            }
            record.add(safetyCheckProjectOverviewVos.get(i));
        }

        safetyCheckOverviewPage.setRecords(record);
        safetyCheckOverviewPage.setTotal(safetyCheckProjectOverviewVos.size());
        return safetyCheckOverviewPage;
    }

    @Override
    public List<SafetyCheckProjectOverviewVo> getSafetyCheckProjectOverviewList(SafetyCheckProjectOverviewListCommand safetyCheckProjectOverviewListCommand) {

        List<SafetyCheckProjectOverviewVo> safetyCheckProjectOverviewVos = new ArrayList<>();
        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return new ArrayList<>();
        }

        AtomicReference<List<OrganizationResp>> allOrganizations = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<SafetyCheckVo>> allSafetyChecks = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<HiddenDangerVo>> allHiddenDangers = new AtomicReference<>(new ArrayList<>());

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allOrganizations.set(organizationRemoteService.getOrganizationList(OrganizationQuery.builder().ids(organizationIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allSafetyChecks.set(safetyCheckRemoteApi.getSafetyCheckList(SafetyCheckQuery.builder()
                        .submitted(true)
                        .checkStartDateTime(safetyCheckProjectOverviewListCommand.getStartDateTime())
                        .checkEndDateTime(safetyCheckProjectOverviewListCommand.getEndDateTime())
                        .build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allHiddenDangers.set(hiddenDangerRemoteApi.getHiddenDangerList(HiddenDangerQuery.builder()
                        .submitted(true)
                        .checkStartDateTime(safetyCheckProjectOverviewListCommand.getStartDateTime())
                        .checkEndDateTime(safetyCheckProjectOverviewListCommand.getEndDateTime())
                        .build())), IO_INSTANCE)
        ).join();

        Map<Long, String> idOrganizationNameMap = new HashMap<>();
        Map<Long, String> idOrganizationFullNameMap = new HashMap<>();
        Map<Long, Integer> idOrganizationDisplayOrderMap = new HashMap<>();

        Map<Long, String> safetyCheckIdSafetyCheckQualityMap = allSafetyChecks.get().stream().collect(Collectors.toMap(SafetyCheckVo::getId, SafetyCheckVo::getSafetyCheckQuality));

        for (OrganizationResp organization : allOrganizations.get()) {
            idOrganizationNameMap.put(organization.getId(), organization.getShortName());
            idOrganizationFullNameMap.put(organization.getId(), organization.getFullName());
            idOrganizationDisplayOrderMap.put(organization.getId(), organization.getDisplayOrder());
        }

        for (ProjectResp project : allProjects.get()) {
            SafetyCheckProjectOverviewVo safetyCheckProjectOverviewVo = SafetyCheckProjectOverviewVo.builder()
                    .name(project.getProjectShortName())
                    .fullName(project.getProjectShortName())
                    .organizationName(idOrganizationNameMap.getOrDefault(project.getHrOrganizationId(), ""))
                    .organizationFullName(idOrganizationFullNameMap.getOrDefault(project.getHrOrganizationId(), ""))
                    .organizationDisplayOrder(idOrganizationDisplayOrderMap.getOrDefault(project.getHrOrganizationId(), Integer.MAX_VALUE))
                    .projectDisplayOrder(project.getId().intValue())
                    .build();

            BigDecimal totalNum = new BigDecimal("0");
            BigDecimal checkProjectNum = new BigDecimal("0");
            BigDecimal hiddenDangerProjectNum = new BigDecimal("0");
            BigDecimal hiddenDangerRectificationProjectNum = new BigDecimal("0");
            BigDecimal checkMajorNum = new BigDecimal("0");
            BigDecimal hiddenDangerMajorNum = new BigDecimal("0");
            BigDecimal hiddenDangerRectificationMajorNum = new BigDecimal("0");
            BigDecimal checkLeaderNum = new BigDecimal("0");
            BigDecimal hiddenDangerLeaderNum = new BigDecimal("0");
            BigDecimal hiddenDangerRectificationLeaderNum = new BigDecimal("0");
            BigDecimal hiddenDangerNum = new BigDecimal("0");
            BigDecimal hiddenDangerRectificationNum = new BigDecimal("0");

            // 统计安全检查数据
            for (SafetyCheckVo safetyCheckVo : allSafetyChecks.get()) {
                if (!project.getId().equals(safetyCheckVo.getProjectId())) {
                    continue;
                }
                totalNum = totalNum.add(new BigDecimal("1"));
                if (safetyCheckVo.getSafetyCheckQuality().equals("项目部检查")) {
                    checkProjectNum = checkProjectNum.add(new BigDecimal("1"));
                }
                if (safetyCheckVo.getSafetyCheckQuality().equals("主体院检查")) {
                    checkMajorNum = checkMajorNum.add(new BigDecimal("1"));
                }
                if (safetyCheckVo.getSafetyCheckQuality().equals("总院检查")) {
                    checkLeaderNum = checkLeaderNum.add(new BigDecimal("1"));
                }
            }

            // 统计安全隐患数据
            for (HiddenDangerVo hiddenDangerVo : allHiddenDangers.get()) {
                if (!project.getId().equals(hiddenDangerVo.getProjectId())) {
                    continue;
                }
                //剔除不属于安全检查下的安全隐患
                if (hiddenDangerVo.getSafetyCheckId() == null) {
                    continue;
                }
                String hiddenDangerInSafetyCheckQuality = safetyCheckIdSafetyCheckQualityMap.get(hiddenDangerVo.getSafetyCheckId());
                //剔除没有检查性质的安全检查
                if (hiddenDangerInSafetyCheckQuality == null) {
                    continue;
                }
                hiddenDangerNum = hiddenDangerNum.add(new BigDecimal("1"));

                if (hiddenDangerInSafetyCheckQuality.equals("项目部检查")) {
                    hiddenDangerProjectNum = hiddenDangerProjectNum.add(new BigDecimal("1"));
                }
                if (hiddenDangerInSafetyCheckQuality.equals("主体院检查")) {
                    hiddenDangerMajorNum = hiddenDangerMajorNum.add(new BigDecimal("1"));
                }
                if (hiddenDangerInSafetyCheckQuality.equals("总院检查")) {
                    hiddenDangerLeaderNum = hiddenDangerLeaderNum.add(new BigDecimal("1"));
                }

                if (hiddenDangerVo.getHiddenDangerStatus().equals("已完成")) {
                    hiddenDangerRectificationNum = hiddenDangerRectificationNum.add(new BigDecimal("1"));

                    if (hiddenDangerInSafetyCheckQuality.equals("项目部检查")) {
                        hiddenDangerRectificationProjectNum = hiddenDangerRectificationProjectNum.add(new BigDecimal("1"));
                    }
                    if (hiddenDangerInSafetyCheckQuality.equals("主体院检查")) {
                        hiddenDangerRectificationMajorNum = hiddenDangerRectificationMajorNum.add(new BigDecimal("1"));
                    }
                    if (hiddenDangerInSafetyCheckQuality.equals("总院检查")) {
                        hiddenDangerRectificationLeaderNum = hiddenDangerRectificationLeaderNum.add(new BigDecimal("1"));
                    }
                }
            }

            safetyCheckProjectOverviewVo.setTotalNum(totalNum);
            safetyCheckProjectOverviewVo.setCheckProjectNum(checkProjectNum);
            safetyCheckProjectOverviewVo.setHiddenDangerProjectNum(hiddenDangerProjectNum);
            safetyCheckProjectOverviewVo.setHiddenDangerRectificationProjectNum(hiddenDangerRectificationProjectNum);
            safetyCheckProjectOverviewVo.setCheckMajorNum(checkMajorNum);
            safetyCheckProjectOverviewVo.setHiddenDangerMajorNum(hiddenDangerMajorNum);
            safetyCheckProjectOverviewVo.setHiddenDangerRectificationMajorNum(hiddenDangerRectificationMajorNum);
            safetyCheckProjectOverviewVo.setCheckLeaderNum(checkLeaderNum);
            safetyCheckProjectOverviewVo.setHiddenDangerLeaderNum(hiddenDangerLeaderNum);
            safetyCheckProjectOverviewVo.setHiddenDangerRectificationLeaderNum(hiddenDangerRectificationLeaderNum);
            safetyCheckProjectOverviewVo.setHiddenDangerNum(hiddenDangerNum);
            safetyCheckProjectOverviewVo.setHiddenDangerRectificationNum(hiddenDangerRectificationNum);

            safetyCheckProjectOverviewVos.add(safetyCheckProjectOverviewVo);
        }

        safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getOrganizationDisplayOrder).reversed().thenComparing(SafetyCheckProjectOverviewVo::getProjectDisplayOrder).reversed()).collect(Collectors.toList());

        if (null != safetyCheckProjectOverviewListCommand.getOrderBy()) {
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("totalNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getTotalNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getTotalNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("checkProjectNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getCheckProjectNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getCheckProjectNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("hiddenDangerProjectNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerProjectNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerProjectNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("rectificationProjectRate")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getRectificationProjectRate)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getRectificationProjectRate).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("hiddenDangerRectificationProjectNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerRectificationProjectNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerRectificationProjectNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("checkMajorNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getCheckMajorNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getCheckMajorNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("hiddenDangerMajorNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerMajorNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerMajorNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("rectificationMajorRate")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getRectificationMajorRate)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getRectificationMajorRate).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("hiddenDangerRectificationMajorNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerRectificationMajorNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerRectificationMajorNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("checkLeaderNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getCheckLeaderNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getCheckLeaderNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("hiddenDangerLeaderNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerLeaderNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerLeaderNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("rectificationLeaderRate")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getRectificationLeaderRate)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getRectificationLeaderRate).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("hiddenDangerRectificationLeaderNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerRectificationLeaderNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerRectificationLeaderNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("hiddenDangerNum")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerNum)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getHiddenDangerNum).reversed()).collect(Collectors.toList());
                }
            }
            if (safetyCheckProjectOverviewListCommand.getOrderBy().equals("rectificationRate")) {
                if (safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getRectificationRate)).collect(Collectors.toList());
                }
                if (!safetyCheckProjectOverviewListCommand.getAsc()) {
                    safetyCheckProjectOverviewVos = safetyCheckProjectOverviewVos.stream().sorted(Comparator.comparing(SafetyCheckProjectOverviewVo::getRectificationRate).reversed()).collect(Collectors.toList());
                }
            }
        }

        return safetyCheckProjectOverviewVos;
    }

    @Override
    @SneakyThrows
    public Page<AttendanceOverviewVo> getAttendanceOverviewPage(AttendanceOverviewPageCommand attendanceOverviewPageCommand) {
        String accessToken = "";

        com.aliyun.dingtalkoauth2_1_0.Client client = createClient();

        com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
                .setAppKey("dingpyvwvsrxdu8jvgji")
                .setAppSecret("xvp5RQOdsqNa2TL5Tt4DRkk_3RzGdJNQ1QkVl1lDvp7cb_h6u3eFmLqZ-JViPk_v");
        try {
            accessToken = client.getAccessToken(getAccessTokenRequest).getBody().accessToken;
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                log.error("钉钉错误码：{}，钉钉错误信息：{}", err.code, err.message);
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                log.error("钉钉错误码：{}，钉钉错误信息：{}", err.code, err.message);
            }

        }

        return null;
    }

    @Override
    public List<AttendanceOverviewVo> getAttendanceOverviewList(AttendanceOverviewListCommand attendanceOverviewListCommand) {
        return null;
    }

    @Override
    public VideoMonitorOrgOverviewPageVo getVideoMonitorOrganizationOverviewPage(VideoMonitorOrganizationOverviewPageCommand videoMonitorOrganizationOverviewPageCommand) {
        List<VideoMonitorOrganizationOverviewVo> records = new ArrayList<>();

        BigDecimal projectNum = new BigDecimal("0");
        BigDecimal notInstallNum = new BigDecimal("0");
        BigDecimal needNum = new BigDecimal("0");
        BigDecimal existNum = new BigDecimal("0");
        BigDecimal stoppedNum = new BigDecimal("0");
        BigDecimal needButNoExistNum = new BigDecimal("0");
        BigDecimal videoNum = new BigDecimal("0");
        BigDecimal inlineNum = new BigDecimal("0");
        BigDecimal outlineNum = new BigDecimal("0");
        BigDecimal defaultNum = new BigDecimal("0");

        long offset = (videoMonitorOrganizationOverviewPageCommand.getCurrent() - 1) * videoMonitorOrganizationOverviewPageCommand.getSize();
        long limit = videoMonitorOrganizationOverviewPageCommand.getCurrent() * videoMonitorOrganizationOverviewPageCommand.getSize();

        List<VideoMonitorOrganizationOverviewVo> videoMonitorOrganizationOverviewVos = this.getVideoMonitorOrganizationOverviewList(adapterConverter.videoMonitorOrganizationOverviewPageCommandToVideoMonitorOrganizationOverviewListCommand(videoMonitorOrganizationOverviewPageCommand));

        for (int i = 0; i < videoMonitorOrganizationOverviewVos.size(); i++) {

            VideoMonitorOrganizationOverviewVo videoMonitorOrganizationOverviewVo = videoMonitorOrganizationOverviewVos.get(i);

            projectNum = projectNum.add(videoMonitorOrganizationOverviewVo.getProjectNum());
            notInstallNum = notInstallNum.add(videoMonitorOrganizationOverviewVo.getNotInstallNum());
            needNum = needNum.add(videoMonitorOrganizationOverviewVo.getNeedNum());
            existNum = existNum.add(videoMonitorOrganizationOverviewVo.getExistNum());
            stoppedNum = stoppedNum.add(videoMonitorOrganizationOverviewVo.getStoppedNum());
            needButNoExistNum = needButNoExistNum.add(videoMonitorOrganizationOverviewVo.getNeedButNoExistNum());
            videoNum = videoNum.add(videoMonitorOrganizationOverviewVo.getVideoNum());
            inlineNum = inlineNum.add(videoMonitorOrganizationOverviewVo.getInlineNum());
            outlineNum = outlineNum.add(videoMonitorOrganizationOverviewVo.getOutlineNum());
            defaultNum = defaultNum.add(videoMonitorOrganizationOverviewVo.getDefaultNum());

            if (i >= offset && i < limit) {
                records.add(videoMonitorOrganizationOverviewVo);
            }
        }

        VideoMonitorOrgOverviewPageVo videoMonitorOrgOverviewPageVo = VideoMonitorOrgOverviewPageVo.builder()
                .projectNum(projectNum)
                .notInstallNum(notInstallNum)
                .needNum(needNum)
                .existNum(existNum)
                .stoppedNum(stoppedNum)
                .needButNoExistNum(needButNoExistNum)
                .videoNum(videoNum)
                .inlineNum(inlineNum)
                .outlineNum(outlineNum)
                .defaultNum(defaultNum)
                .build();

        videoMonitorOrgOverviewPageVo.setCurrent((int) videoMonitorOrganizationOverviewPageCommand.getCurrent());
        videoMonitorOrgOverviewPageVo.setSize((int) videoMonitorOrganizationOverviewPageCommand.getSize());
        videoMonitorOrgOverviewPageVo.setRecords(records);
        videoMonitorOrgOverviewPageVo.setTotal(videoMonitorOrganizationOverviewVos.size());

        return videoMonitorOrgOverviewPageVo;
    }

    @Override
    public List<VideoMonitorOrganizationOverviewVo> getVideoMonitorOrganizationOverviewList(VideoMonitorOrganizationOverviewListCommand videoMonitorOrganizationOverviewListCommand) {

        List<VideoMonitorOrganizationOverviewVo> videoMonitorOrganizationOverviewVos;
        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return new ArrayList<>();
        }

        AtomicReference<List<OrganizationResp>> allOrganizations = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<VideoMonitor>> allVideoMonitors = new AtomicReference<>(new ArrayList<>());

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allOrganizations.set(organizationRemoteService.getOrganizationList(OrganizationQuery.builder().ids(organizationIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allVideoMonitors.set(videoMonitorRemoteApi.getVideoMonitorList(VideoMonitorQuery.builder().build())), IO_INSTANCE)
        ).join();

        Map<Long, Long> projectIdOrganizationIdMap = new HashMap<>();
        for (ProjectResp projectResp : allProjects.get()) {
            projectIdOrganizationIdMap.put(projectResp.getId(), projectResp.getHrOrganizationId());
        }

        Map<Long, OrganizationResp> organizationIdOrganizationMap = new HashMap<>();
        for (OrganizationResp organizationResp : allOrganizations.get()) {
            organizationIdOrganizationMap.put(organizationResp.getId(), organizationResp);
        }

        Map<Long, List<VideoMonitor>> projectIdVideoMonitorsMap = new HashMap<>();
        for (VideoMonitor videoMonitor : allVideoMonitors.get()) {
            List<VideoMonitor> videoMonitorsByProjectId = projectIdVideoMonitorsMap.getOrDefault(videoMonitor.getProjectId(), new ArrayList<>());
            videoMonitorsByProjectId.add(videoMonitor);
            projectIdVideoMonitorsMap.put(videoMonitor.getProjectId(), videoMonitorsByProjectId);
        }

        Map<Long, VideoMonitorOrganizationOverviewVo> organizationIdResultMap = new HashMap<>();
        for (ProjectResp project : allProjects.get()) {
            Long projectId = project.getId();
            Long organizationId = projectIdOrganizationIdMap.get(projectId);
            OrganizationResp organization = organizationIdOrganizationMap.get(organizationId);
            if (null == organization) {
                continue;
            }
            List<VideoMonitor> videoMonitorsByProjectId = projectIdVideoMonitorsMap.getOrDefault(projectId, new ArrayList<>());

            VideoMonitorOrganizationOverviewVo videoMonitorOrganizationOverviewVo = organizationIdResultMap.getOrDefault(organizationId, VideoMonitorOrganizationOverviewVo.builder()
                    .name(organization.getShortName())
                    .fullName(organization.getFullName())
                    .projectNum(new BigDecimal("0"))
                    .defaultNum(new BigDecimal("0"))
                    .notInstallNum(new BigDecimal("0"))
                    .stoppedNum(new BigDecimal("0"))
                    .needNum(new BigDecimal("0"))
                    .existNum(new BigDecimal("0"))
                    .needButNoExistNum(new BigDecimal("0"))
                    .videoNum(new BigDecimal("0"))
                    .inlineNum(new BigDecimal("0"))
                    .outlineNum(new BigDecimal("0"))
                    .organizationDisplayOrder(organization.getDisplayOrder())
                    .build());

            BigDecimal projectNum = videoMonitorOrganizationOverviewVo.getProjectNum();
            BigDecimal defaultNum = videoMonitorOrganizationOverviewVo.getDefaultNum();
            BigDecimal notInstallNum = videoMonitorOrganizationOverviewVo.getNotInstallNum();
            BigDecimal needNum = videoMonitorOrganizationOverviewVo.getNeedNum();
            BigDecimal existNum = videoMonitorOrganizationOverviewVo.getExistNum();
            BigDecimal stoppedNum = videoMonitorOrganizationOverviewVo.getStoppedNum();
            BigDecimal needButNoExistNum = videoMonitorOrganizationOverviewVo.getNeedButNoExistNum();
            BigDecimal videoNum = videoMonitorOrganizationOverviewVo.getVideoNum();
            BigDecimal inlineNum = videoMonitorOrganizationOverviewVo.getInlineNum();
            BigDecimal outlineNum = videoMonitorOrganizationOverviewVo.getOutlineNum();

            // 统计项目数据
            if (project.getProjectStatus().equals(NOT_STARTED.name()) || project.getProjectStatus().equals(CONSTRUCTING.name()) || project.getProjectStatus().equals(STOPPED.name())) {
                projectNum = projectNum.add(new BigDecimal("1"));
                if (project.getMonitorType().equals(DEFAULT_TYPE.name())) {
                    defaultNum = defaultNum.add(new BigDecimal("1"));
                }
                if (project.getMonitorType().equals(NOT_INSTALLED.name())) {
                    notInstallNum = notInstallNum.add(new BigDecimal("1"));
                }
                if (project.getMonitorType().equals(ConstantField.MonitorTypeEnum.STOPPED.name())) {
                    stoppedNum = stoppedNum.add(new BigDecimal("1"));
                }
                if (!project.getMonitorType().equals(NOT_INSTALLED.name())) {
                    needNum = needNum.add(new BigDecimal("1"));
                    if (!videoMonitorsByProjectId.isEmpty()) {
                        existNum = existNum.add(new BigDecimal("1"));
                        for (VideoMonitor videoMonitor : videoMonitorsByProjectId) {
                            videoNum = videoNum.add(new BigDecimal("1"));
                            if (videoMonitor.getStatus().equals("在线")) {
                                inlineNum = inlineNum.add(new BigDecimal("1"));
                            }
                            if (videoMonitor.getStatus().equals("离线")) {
                                outlineNum = outlineNum.add(new BigDecimal("1"));
                            }
                        }
                    }
                    if (videoMonitorsByProjectId.isEmpty()) {
                        needButNoExistNum = needButNoExistNum.add(new BigDecimal("1"));
                    }
                }
            }

            videoMonitorOrganizationOverviewVo.setProjectNum(projectNum);
            videoMonitorOrganizationOverviewVo.setDefaultNum(defaultNum);
            videoMonitorOrganizationOverviewVo.setNotInstallNum(notInstallNum);
            videoMonitorOrganizationOverviewVo.setStoppedNum(stoppedNum);
            videoMonitorOrganizationOverviewVo.setNeedNum(needNum);
            videoMonitorOrganizationOverviewVo.setExistNum(existNum);
            videoMonitorOrganizationOverviewVo.setNeedButNoExistNum(needButNoExistNum);
            videoMonitorOrganizationOverviewVo.setVideoNum(videoNum);
            videoMonitorOrganizationOverviewVo.setInlineNum(inlineNum);
            videoMonitorOrganizationOverviewVo.setOutlineNum(outlineNum);

            organizationIdResultMap.put(organizationId, videoMonitorOrganizationOverviewVo);
        }

        if (organizationIdResultMap.values().isEmpty()) {
            return new ArrayList<>();
        }
        videoMonitorOrganizationOverviewVos = organizationIdResultMap.values().stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getOrganizationDisplayOrder)).collect(Collectors.toList());


        if (null != videoMonitorOrganizationOverviewListCommand.getOrderBy()) {
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("projectNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getProjectNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getProjectNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("defaultNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getDefaultNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getDefaultNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("notInstallNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getNotInstallNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getNotInstallNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("stoppedNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getStoppedNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getStoppedNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("needNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getNeedNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getNeedNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("existNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getExistNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getExistNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("needButNoExistNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getNeedButNoExistNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getNeedButNoExistNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("videoNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getVideoNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getVideoNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("inlineNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getInlineNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getInlineNum).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorOrganizationOverviewListCommand.getOrderBy().equals("outlineNum")) {
                if (videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getOutlineNum)).collect(Collectors.toList());
                }
                if (!videoMonitorOrganizationOverviewListCommand.getAsc()) {
                    videoMonitorOrganizationOverviewVos = videoMonitorOrganizationOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorOrganizationOverviewVo::getOutlineNum).reversed()).collect(Collectors.toList());
                }
            }
        }

        return videoMonitorOrganizationOverviewVos;
    }

    @Override
    public Page<VideoMonitorProjectOverviewVo> getVideoMonitorProjectOverviewPage(VideoMonitorProjectOverviewPageCommand videoMonitorProjectOverviewPageCommand) {
        Page<VideoMonitorProjectOverviewVo> videoMonitorProjectOverviewPage = new Page<>(videoMonitorProjectOverviewPageCommand.getCurrent(), videoMonitorProjectOverviewPageCommand.getSize());
        List<VideoMonitorProjectOverviewVo> record = new ArrayList<>();

        long offset = (videoMonitorProjectOverviewPageCommand.getCurrent() - 1) * videoMonitorProjectOverviewPageCommand.getSize();
        long limit = videoMonitorProjectOverviewPageCommand.getCurrent() * videoMonitorProjectOverviewPageCommand.getSize();

        List<VideoMonitorProjectOverviewVo> videoMonitorProjectOverviewVos = this.getVideoMonitorProjectOverviewList(adapterConverter.videoMonitorProjectOverviewPageCommandToVideoMonitorProjectOverviewListCommand(videoMonitorProjectOverviewPageCommand));

        for (int i = (int) offset; i < limit; i++) {
            if (i >= videoMonitorProjectOverviewVos.size()) {
                continue;
            }
            record.add(videoMonitorProjectOverviewVos.get(i));
        }

        videoMonitorProjectOverviewPage.setRecords(record);
        videoMonitorProjectOverviewPage.setTotal(videoMonitorProjectOverviewVos.size());

        return videoMonitorProjectOverviewPage;
    }

    @Override
    public List<VideoMonitorProjectOverviewVo> getVideoMonitorProjectOverviewList(VideoMonitorProjectOverviewListCommand videoMonitorProjectOverviewListCommand) {

        List<VideoMonitorProjectOverviewVo> videoMonitorProjectOverviewVos = new ArrayList<>();
        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        if (organizationIds.isEmpty()) {
            return new ArrayList<>();
        }
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return new ArrayList<>();
        }

        AtomicReference<List<OrganizationResp>> allOrganizations = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<VideoMonitor>> allVideoMonitors = new AtomicReference<>(new ArrayList<>());

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allOrganizations.set(organizationRemoteService.getOrganizationList(OrganizationQuery.builder().ids(organizationIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allVideoMonitors.set(videoMonitorRemoteApi.getVideoMonitorList(VideoMonitorQuery.builder().build())), IO_INSTANCE)
        ).join();

        Map<Long, String> idOrganizationNameMap = new HashMap<>();
        Map<Long, String> idOrganizationFullNameMap = new HashMap<>();
        Map<Long, Integer> idOrganizationDisplayOrderMap = new HashMap<>();
        for (OrganizationResp organization : allOrganizations.get()) {
            idOrganizationNameMap.put(organization.getId(), organization.getShortName());
            idOrganizationFullNameMap.put(organization.getId(), organization.getFullName());
            idOrganizationDisplayOrderMap.put(organization.getId(), organization.getDisplayOrder());
        }

        for (ProjectResp project : allProjects.get()) {
            VideoMonitorProjectOverviewVo videoMonitorProjectOverviewVo = VideoMonitorProjectOverviewVo.builder()
                    .name(project.getProjectShortName())
                    .fullName(project.getProjectShortName())
                    .organizationName(idOrganizationNameMap.getOrDefault(project.getHrOrganizationId(), ""))
                    .organizationFullName(idOrganizationFullNameMap.getOrDefault(project.getHrOrganizationId(), ""))
                    .projectStatus(project.getProjectStatus())
                    .organizationDisplayOrder(idOrganizationDisplayOrderMap.getOrDefault(project.getHrOrganizationId(), Integer.MAX_VALUE))
                    .projectDisplayOrder(project.getId().intValue())
                    .build();

            BigDecimal videoNum = new BigDecimal("0");
            BigDecimal inlineNum = new BigDecimal("0");
            BigDecimal outlineNum = new BigDecimal("0");

            // 统计视频监控数据
            for (VideoMonitor videoMonitor : allVideoMonitors.get()) {
                if (!project.getId().equals(videoMonitor.getProjectId())) {
                    continue;
                }
                videoNum = videoNum.add(new BigDecimal("1"));
                if (videoMonitor.getStatus().equals("在线")) {
                    inlineNum = inlineNum.add(new BigDecimal("1"));
                }
                if (videoMonitor.getStatus().equals("离线")) {
                    outlineNum = outlineNum.add(new BigDecimal("1"));
                }
            }

            if (project.getProjectStatus().equals(STOPPED.name())) {
                videoMonitorProjectOverviewVo.setMonitorOnlineStatus(STOP.name());
                videoMonitorProjectOverviewVos.add(videoMonitorProjectOverviewVo);
                continue;
            }
            if (project.getProjectStatus().equals(FINISHED.name())) {
                videoMonitorProjectOverviewVo.setMonitorOnlineStatus(FINISH.name());
                videoMonitorProjectOverviewVos.add(videoMonitorProjectOverviewVo);
                continue;
            }
            if (project.getMonitorType().equals(NOT_INSTALLED.name())) {
                videoMonitorProjectOverviewVo.setMonitorOnlineStatus(NOT_INSTALL.name());
                videoMonitorProjectOverviewVos.add(videoMonitorProjectOverviewVo);
                continue;
            }
            if (project.getMonitorType().equals(STOPPED.name())) {
                videoMonitorProjectOverviewVo.setMonitorOnlineStatus(PAUSE.name());
                videoMonitorProjectOverviewVos.add(videoMonitorProjectOverviewVo);
                continue;
            }
            if (videoNum.compareTo(new BigDecimal("0")) > 0) {
                videoMonitorProjectOverviewVo.setMonitorOnlineStatus(INLINE.name());
            }
            if (videoNum.compareTo(new BigDecimal("0")) == 0) {
                videoMonitorProjectOverviewVo.setMonitorOnlineStatus(OUTLINE.name());
            }

            videoMonitorProjectOverviewVo.setVideoNum(videoNum);
            videoMonitorProjectOverviewVo.setInlineNum(inlineNum);
            videoMonitorProjectOverviewVo.setOutlineNum(outlineNum);

            videoMonitorProjectOverviewVos.add(videoMonitorProjectOverviewVo);
        }

        videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getOrganizationDisplayOrder).reversed().thenComparing(VideoMonitorProjectOverviewVo::getProjectDisplayOrder).reversed()).collect(Collectors.toList());

        if (null != videoMonitorProjectOverviewListCommand.getOrderBy()) {
            if (videoMonitorProjectOverviewListCommand.getOrderBy().equals("projectStatus")) {
                if (videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getProjectStatus)).collect(Collectors.toList());
                }
                if (!videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getProjectStatus).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorProjectOverviewListCommand.getOrderBy().equals("monitorOnlineStatus")) {
                if (videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getMonitorOnlineStatus)).collect(Collectors.toList());
                }
                if (!videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getMonitorOnlineStatus).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorProjectOverviewListCommand.getOrderBy().equals("videoNum")) {
                if (videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getVideoNum, Comparator.nullsLast(BigDecimal::compareTo))).collect(Collectors.toList());
                }
                if (!videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getVideoNum, Comparator.nullsFirst(BigDecimal::compareTo)).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorProjectOverviewListCommand.getOrderBy().equals("inlineNum")) {
                if (videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getInlineNum, Comparator.nullsLast(BigDecimal::compareTo))).collect(Collectors.toList());
                }
                if (!videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getInlineNum, Comparator.nullsFirst(BigDecimal::compareTo)).reversed()).collect(Collectors.toList());
                }
            }
            if (videoMonitorProjectOverviewListCommand.getOrderBy().equals("outlineNum")) {
                if (videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getOutlineNum, Comparator.nullsLast(BigDecimal::compareTo))).collect(Collectors.toList());
                }
                if (!videoMonitorProjectOverviewListCommand.getAsc()) {
                    videoMonitorProjectOverviewVos = videoMonitorProjectOverviewVos.stream().sorted(Comparator.comparing(VideoMonitorProjectOverviewVo::getOutlineNum, Comparator.nullsFirst(BigDecimal::compareTo)).reversed()).collect(Collectors.toList());
                }
            }
        }

        return videoMonitorProjectOverviewVos;
    }

    public static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }

    @Override
    public Page<DingAttendanceOverViewVo> getDingAttendanceOverViewPage(DingAttendanceOverViewPageCommand dingAttendanceOverViewPageCommand) {
        Page<DingAttendanceOverViewVo> page = new Page<>(dingAttendanceOverViewPageCommand.getCurrent(), dingAttendanceOverViewPageCommand.getSize());
        List<DingAttendanceOverViewVo> records = new ArrayList<>();
        //获取所有记录
        getDingAttendanceOverViewPageOrg(dingAttendanceOverViewPageCommand, records);
        //排序
        records = sortRecords(records, dingAttendanceOverViewPageCommand);
        //分页
        long offset = (dingAttendanceOverViewPageCommand.getCurrent() - 1) * dingAttendanceOverViewPageCommand.getSize();
        long limit = dingAttendanceOverViewPageCommand.getSize() * dingAttendanceOverViewPageCommand.getCurrent();
        List<DingAttendanceOverViewVo> list = new ArrayList<>();
        for (int i = (int) offset; i < limit; i++) {
            if (i >= records.size()) {
                break;
            }
            list.add(records.get(i));
        }
        page.setRecords(list);
        page.setTotal(records.size());
        return page;
    }


    private List<DingAttendanceOverViewVo> sortRecords(List<DingAttendanceOverViewVo> records, DingAttendanceOverViewPageCommand command) {
        if (null != command.getOrderBy()) {
            if (command.getOrderBy().equals("unPassProjectNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getUnPassProjectNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getUnPassProjectNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("projectNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getProjectNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getProjectNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("reportPersonNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getReportPersonNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getReportPersonNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("passReportPersonNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getPassReportPersonNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getPassReportPersonNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("unPassReportPersonNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getUnPassReportPersonNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getUnPassReportPersonNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("attendanceNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getAttendanceNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getAttendanceNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("avgAttendanceFloat")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getAvgAttendanceFloat)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceOverViewVo::getAvgAttendanceFloat).reversed()).collect(Collectors.toList());
                }
            }
        }
        return records;
    }

    private void getDingAttendanceOverViewPageOrg(DingAttendanceOverViewPageCommand dingAttendanceOverViewPageCommand, List<DingAttendanceOverViewVo> records) {
        List<Long> orgIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        if (orgIds.isEmpty()) {
            return;
        }
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return;
        }

        List<AllOrganizationResp> pageOrg = organizationRemoteService.getOrganizationList(orgIds);
        //遍历分页后的院级组织
        for (AllOrganizationResp allOrganizationResp : pageOrg) {
            DingAttendanceOverViewVo viewVo = new DingAttendanceOverViewVo();
            /* 设置院名称 */
            String shortName = allOrganizationResp.getShortName();
            viewVo.setOrgName(shortName);
            /* 设置ID */
            viewVo.setId(allOrganizationResp.getId());
            //获取组织下对应上的项目
            List<ProjectWithDingResp> projectWithDingResps = projectRemoteService.getProjectResponseDataByOrgId(allOrganizationResp.getId(), projectIds);
            //对应项目为空，返回默认值
            if (projectWithDingResps.size() == 0) {
                initSetDingAttendanceOverViewVo(viewVo);
                records.add(viewVo);
                log.info("组织：{}下项目数量为空，返回默认值", shortName);
                continue;
            }
            //不为空，查询每个项目人数及打卡情况
            /* 设置项目总数 */
            viewVo.setProjectNumber(projectWithDingResps.size());
            int unPassProject = 0; //不合格项目数
            int passPersons = 0; //合格人数
            int unPassPerson = 0; //不合格人数
            int reportCount = 0; //打卡总天数
            int reportPersons = 0; //上报打卡人数
            //遍历项目，根据项目dingDeptKey查询打卡记录，人数等信息
            for (ProjectWithDingResp project : projectWithDingResps) {
                String projectType = project.getProjectType();
                String dingDeptKey = project.getDingDeptKey();
                String epcType = project.getEpcType();
                List<String> userIds = null;
                if (dingDeptKey != null) {
                    userIds = dingDeptUserRepository.getUserIdsByDeptKey(dingDeptKey);
                }
                //当项目关联人数为0时，该项目直接判定不合格
                if (userIds == null || userIds.size() == 0) {
                    unPassProject++;
                    log.error("组织：{}下项目：{},不合格", shortName, project.getProjectShortName());
                } else {
                    int userNum = userIds.size();
                    //不为0时，打卡人数相加
                    reportPersons += userNum;
                    boolean isUnPassProject = false;
                    //获取人员打卡记录
                    List<DingAttendanceResultEntity> resultEntities = attendanceResultRepository.getRecordByUserIdAndWorkDate(userIds, dingAttendanceOverViewPageCommand.getTime());
                    Map<String, List<DingAttendanceResultEntity>> map = resultEntities.stream().collect(Collectors.groupingBy(DingAttendanceResultEntity::getUserId));
                    for (String userId : userIds) {
                        //获取用户当月打卡次数
                        List<DingAttendanceResultEntity> results = map.get(userId);
                        DingPassPersonVo vo = isPassPerson(results);
                        if (vo.isPass()) {
                            passPersons++;
                        } else {
                            unPassPerson++;
                            isUnPassProject = true;
                        }
                        reportCount += vo.getDays();
                    }
                    if (isUnPassProject || projectType == null || epcType == null || userIds.size() < ProjectTypeEnum.getCount(projectType, epcType) || ProjectTypeEnum.getCount(projectType, epcType) == 0) {
                        unPassProject++;
                    }
                }
            }
            /* 设置总体评价 */
            viewVo.setEvaluate(unPassProject > 0 ? DingDing.NO_PASS : DingDing.PASS);
            /* 设置不合格项目数 */
            viewVo.setUnPassProjectNumber(unPassProject);
            /* 设置上报打卡人数 */
            viewVo.setReportPersonNumber(reportPersons);
            /* 设置打卡合格人数 */
            viewVo.setPassReportPersonNumber(passPersons);
            /* 设置打卡不合格人数 */
            viewVo.setUnPassReportPersonNumber(unPassPerson);
            /* 设置打卡总天数 */
            viewVo.setAttendanceNumber(reportCount);
            /* 设置人均打卡天数 */
            float avgAttendance = reportCount / (float) reportPersons;
            viewVo.setAvgAttendanceFloat((float) Math.round(avgAttendance * 100) / 100);
            records.add(viewVo);
        }

    }

    private DingPassPersonVo isPassPerson(List<DingAttendanceResultEntity> results) {
        DingPassPersonVo dingPassPersonVo = new DingPassPersonVo();
        dingPassPersonVo.setPass(false);
        if (CollectionUtils.isEmpty(results)) {
            dingPassPersonVo.setDays(0);
            return dingPassPersonVo;
        }
        //以日期分类,如果小于20天直接返回不合格
        Map<LocalDate, List<String>> map = results.stream().collect(Collectors.groupingBy(DingAttendanceResultEntity::getWorkDate, Collectors.mapping(DingAttendanceResultEntity::getTimeResult, Collectors.toList())));
        dingPassPersonVo.setDays(map.size());
        if (map.size() < 20) {
            return dingPassPersonVo;
        }
        int count = 0;
        //获取每天打卡结果，如果每天打卡结果正常，则正常天数加1
        for (Map.Entry<LocalDate, List<String>> entry : map.entrySet()) {
            List<String> timeResults = entry.getValue();
            if (timeResults.stream().anyMatch("Normal"::equals)) {
                count++;
            }
        }
        //当一个月打卡合格天数>=20时，该员工打卡合格
        if (count >= 20) {
            dingPassPersonVo.setPass(true);
            return dingPassPersonVo;
        }
        return dingPassPersonVo;
    }

    private void initSetDingAttendanceOverViewVo(DingAttendanceOverViewVo viewVo) {
        viewVo.setEvaluate("暂无");
        viewVo.setUnPassProjectNumber(0);
        viewVo.setProjectNumber(0);
        viewVo.setReportPersonNumber(0);
        viewVo.setPassReportPersonNumber(0);
        viewVo.setUnPassReportPersonNumber(0);
        viewVo.setAttendanceNumber(0);
        viewVo.setAvgAttendanceFloat(0.00F);
    }

    @Override
    public Page<DingAttendanceProjectOverViewVo> getDingAttendanceProjectOverViewPage(DingAttendanceProjectOverViewPageCommand dingAttendanceOverViewPageCommand) {
        Page<DingAttendanceProjectOverViewVo> page = new Page<>(dingAttendanceOverViewPageCommand.getCurrent(), dingAttendanceOverViewPageCommand.getSize());
        //获取所有记录
        List<DingAttendanceProjectOverViewVo> records = getDingAttendanceProjectOverViewPage(dingAttendanceOverViewPageCommand.getTime(), null);
        //判断是否只显示不合格项目
        if (dingAttendanceOverViewPageCommand.getPass()) {
            records = records.stream().filter(dingAttendanceProjectOverViewVo -> DingDing.NO_PASS.equals(dingAttendanceProjectOverViewVo.getEvaluate())).collect(Collectors.toList());
        }
        //排序
        records = sortProjectRecords(dingAttendanceOverViewPageCommand, records);
        //分页
        long offset = (dingAttendanceOverViewPageCommand.getCurrent() - 1) * dingAttendanceOverViewPageCommand.getSize();
        long limit = dingAttendanceOverViewPageCommand.getSize() * dingAttendanceOverViewPageCommand.getCurrent();
        List<DingAttendanceProjectOverViewVo> pageRecords = new ArrayList<>();
        for (int i = (int) offset; i < limit; i++) {
            if (i >= records.size()) {
                break;
            }
            pageRecords.add(records.get(i));
        }
        page.setRecords(pageRecords);
        page.setTotal(records.size());
        return page;
    }

    @Override
    public Page<DingAttendanceProjectOverViewVo> getDingAttendanceProjectDetailOverViewPage(DingProjectDetailPageCommand command) {
        Page<DingAttendanceProjectOverViewVo> page = new Page<>(command.getCurrent(), command.getSize());
        //获取所有记录
        List<DingAttendanceProjectOverViewVo> records = getDingAttendanceProjectOverViewPage(command.getTime(), command.getOrgId());
        //判断是否只显示不合格项目
        records = records.stream().filter(dingAttendanceProjectOverViewVo -> DingDing.NO_PASS.equals(dingAttendanceProjectOverViewVo.getEvaluate())).collect(Collectors.toList());
        //分页
        long offset = (command.getCurrent() - 1) * command.getSize();
        long limit = command.getSize() * command.getCurrent();
        List<DingAttendanceProjectOverViewVo> pageRecords = new ArrayList<>();
        for (int i = (int) offset; i < limit; i++) {
            if (i >= records.size()) {
                break;
            }
            pageRecords.add(records.get(i));
        }
        page.setRecords(pageRecords);
        page.setTotal(records.size());
        return page;
    }

    @Override
    public Page<DingPeopleDetailOverViewVo> getDingAttendancePeopleDetailOverViewPage(DingProjectDetailPageCommand command) {
        Page<DingPeopleDetailOverViewVo> page = new Page<>(command.getCurrent(), command.getSize());
        List<Long> orgIds = new ArrayList<>();
        orgIds.add(command.getOrgId());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return page;
        }
        //获取所有对应上的院级组织
        List<AllOrganizationResp> allOrganizationResps = organizationRemoteService.getOrganizationList(orgIds);
        int size = allOrganizationResps.size();
        if (size == 0) {
            return page;
        }
        //获取所有主体院项目与用户ID对应情况
        List<DingDeptUser> userIdAndDeptKey = dingDeptUserRepository.getAllUserIdAndDeptKey();
        Map<String, List<DingDeptUser>> people = userIdAndDeptKey.stream().collect(Collectors.groupingBy(DingDeptUser::getUserId));
        List<DingPeopleDetailOverViewVo> records = new ArrayList<>();
        for (AllOrganizationResp resp : allOrganizationResps) {
            String shortName = resp.getShortName();
            //获取组织下对应上的正在建设中的项目
            List<ProjectWithDingResp> projectWithDingResps = projectRemoteService.getProjectResponseDataByOrgId(resp.getId(), projectIds);
            //对应项目为空，跳过
            if (projectWithDingResps.size() == 0) {
                log.info("组织：{}下项目数量为空，跳过", shortName);
                continue;
            }
            //不为空，查询每个项目人数及打卡情况
            //遍历项目，根据项目dingDeptKey查询打卡记录，人数等信息
            for (ProjectWithDingResp project : projectWithDingResps) {
                String dingDeptKey = project.getDingDeptKey();
                List<String> userIds = null;
                if (dingDeptKey != null) {
                    userIds = userIdAndDeptKey.stream().filter(dingDeptUser -> dingDeptUser.getDingDeptKey().equals(dingDeptKey)).map(DingDeptUser::getUserId).collect(Collectors.toList());
                }
                if (CollectionUtils.isEmpty(userIds)) {
                    continue;
                }
                List<DingAttendanceResultEntity> resultEntities = attendanceResultRepository.getRecordByUserIdAndWorkDate(userIds, command.getTime());
                Map<String, List<DingAttendanceResultEntity>> map = resultEntities.stream().collect(Collectors.groupingBy(DingAttendanceResultEntity::getUserId));
                for (String userId : userIds) {
                    //获取用户当月打卡次数
                    List<DingAttendanceResultEntity> results = map.get(userId);
                    DingPassPersonVo personVo = isPassPerson(results);
                    if (!personVo.isPass()) {
                        DingPeopleDetailOverViewVo vo = new DingPeopleDetailOverViewVo();
                        vo.setProjectName(project.getProjectShortName());
                        vo.setName(people.get(userId).get(0).getName());
                        vo.setProjectJob(people.get(userId).get(0).getProjectJob());
                        vo.setAttendanceNumber(personVo.getDays());
                        records.add(vo);
                    }
                }
            }
        }
        //分页
        long offset = (command.getCurrent() - 1) * command.getSize();
        long limit = command.getSize() * command.getCurrent();
        List<DingPeopleDetailOverViewVo> pageRecords = new ArrayList<>();
        for (int i = (int) offset; i < limit; i++) {
            if (i >= records.size()) {
                break;
            }
            pageRecords.add(records.get(i));
        }
        page.setRecords(pageRecords);
        page.setTotal(records.size());
        return page;
    }

    private List<DingAttendanceProjectOverViewVo> getDingAttendanceProjectOverViewPage(String time, Long orgId) {
        List<Long> orgIds;
        if (orgId == null) {
            orgIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        } else {
            orgIds = new ArrayList<>();
            orgIds.add(orgId);
        }
        if (orgIds.isEmpty()) {
            return new ArrayList<>();
        }
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return new ArrayList<>();
        }
        //获取所有对应上的院级组织
        List<AllOrganizationResp> allOrganizationResps = organizationRemoteService.getOrganizationList(orgIds);
        //获取所有主体院项目与用户ID对应情况
        List<DingDeptUser> userIdAndDeptKey = dingDeptUserRepository.getAllUserIdAndDeptKey();
        List<DingAttendanceProjectOverViewVo> records = new ArrayList<>();
        int size = allOrganizationResps.size();
        if (size == 0) {
            return new ArrayList<>();
        }
        //遍历过滤后的院级组织
        for (AllOrganizationResp resp : allOrganizationResps) {
            String shortName = resp.getShortName();
            //获取组织下对应上的正在建设中的项目
            List<ProjectWithDingResp> projectWithDingResps = projectRemoteService.getProjectResponseDataByOrgId(resp.getId(), projectIds);
            //对应项目为空，跳过
            if (projectWithDingResps.size() == 0) {
                log.info("组织：{}下项目数量为空，跳过", shortName);
                continue;
            }
            //不为空，查询每个项目人数及打卡情况
            //遍历项目，根据项目dingDeptKey查询打卡记录，人数等信息
            for (ProjectWithDingResp project : projectWithDingResps) {
                DingAttendanceProjectOverViewVo view = new DingAttendanceProjectOverViewVo();
                /* 设置院名称 */
                view.setOrgName(shortName);
                /* 设置ID */
                view.setId(project.getId());
                /* 设置项目名称 */
                view.setProjectName(project.getProjectShortName());
                view.setEpcType(project.getEpcType());
                view.setProjectType(project.getProjectType());
                String projectType = project.getProjectType();
                String dingDeptKey = project.getDingDeptKey();
                String epcType = project.getEpcType();
                List<String> userIds = null;
                if (dingDeptKey != null) {
                    userIds = userIdAndDeptKey.stream().filter(dingDeptUser -> dingDeptUser.getDingDeptKey().equals(dingDeptKey)).map(DingDeptUser::getUserId).collect(Collectors.toList());
                }
                //当项目关联人数为0时，该项目直接判定不合格
                if (userIds == null || userIds.size() == 0) {
                    view.setEvaluate(DingDing.NO_PASS);
                    view.setReportPersonNumber(0);
                    view.setPassReportPersonNumber(0);
                    view.setUnPassReportPersonNumber(0);
                    view.setAttendanceNumber(0);
                    view.setAvgAttendanceFloat(0.0F);
                    records.add(view);
                    log.error("组织：{}下项目：{}关联人数为0,不合格", shortName, project.getProjectShortName());
                    continue;
                }
                int userNum = userIds.size();
                /* 设置打卡人数 */
                view.setReportPersonNumber(userNum);
                int passPersons = 0; //合格人数
                int unPassPerson = 0; //不合格人数
                int reportCount = 0; //打卡总天数
                //获取人员打卡记录
                List<DingAttendanceResultEntity> resultEntities = attendanceResultRepository.getRecordByUserIdAndWorkDate(userIds, time);
                Map<String, List<DingAttendanceResultEntity>> map = resultEntities.stream().collect(Collectors.groupingBy(DingAttendanceResultEntity::getUserId));
                for (String userId : userIds) {
                    //获取用户当月打卡次数
                    List<DingAttendanceResultEntity> results = map.get(userId);
                    DingPassPersonVo vo = isPassPerson(results);
                    if (vo.isPass()) {
                        passPersons++;
                    } else {
                        unPassPerson++;
                    }
                    reportCount += vo.getDays();
                }
                /* 设置合格人数 */
                view.setPassReportPersonNumber(passPersons);
                /* 设置不合格人数 */
                view.setUnPassReportPersonNumber(unPassPerson);
                /* 设置打卡总数 */
                view.setAttendanceNumber(reportCount);
                //根据总人数和项目等级判断是否合格
                if (projectType == null || epcType == null || userNum < ProjectTypeEnum.getCount(projectType, epcType) || ProjectTypeEnum.getCount(projectType, epcType) == 0) {
                    view.setEvaluate(DingDing.NO_PASS);
                    log.error("组织：{}下项目：{}总人数为:{},项目等级为:{},要求人数为:{}.不合格", shortName, project.getProjectShortName(), userNum, projectType, ProjectTypeEnum.getCount(projectType, epcType));
                } else {
                    view.setEvaluate(DingDing.PASS);
                }
                if (unPassPerson > 0) {
                    view.setEvaluate(DingDing.NO_PASS);
                }
                float avgAttendance = reportCount / (float) userNum;
                //设置平均打卡数
                view.setAvgAttendanceFloat((float) Math.round(avgAttendance * 100) / 100);
                records.add(view);
            }
        }
        return records;
    }

    private List<DingAttendanceProjectOverViewVo> sortProjectRecords(DingAttendanceProjectOverViewPageCommand command, List<DingAttendanceProjectOverViewVo> records) {
        if (null != command.getOrderBy()) {
            if (command.getOrderBy().equals("reportPersonNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getReportPersonNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getReportPersonNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("passReportPersonNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getPassReportPersonNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getPassReportPersonNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("unPassReportPersonNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getUnPassReportPersonNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getUnPassReportPersonNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("attendanceNumber")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getAttendanceNumber)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getAttendanceNumber).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("avgAttendanceFloat")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getAvgAttendanceFloat)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(DingAttendanceProjectOverViewVo::getAvgAttendanceFloat).reversed()).collect(Collectors.toList());
                }
            }
        }
        return records;
    }

    @Override
    public DingDingAttendanceProjectVo getDingDingAttendanceProjectVo(DingDingProjectRequest dingDingProjectRequest) {
        Long projectId = dingDingProjectRequest.getProjectId();
        ProjectWithDingResp projectWithDingResp = projectRemoteService.getProjectById(projectId);
        DingDingAttendanceProjectVo dingDingAttendanceProjectVo = new DingDingAttendanceProjectVo();
        dingDingAttendanceProjectVo.setId(projectId);
        dingDingAttendanceProjectVo.setProjectName(projectWithDingResp.getProjectShortName());
        //判断项目有没有与钉钉关联，未关联直接返回默认数据
        if (projectWithDingResp.getDingDeptKey() != null) {
            List<DingDeptUser> list = dingDeptUserRepository.getListByDeptKey(projectWithDingResp.getDingDeptKey());
            //判断项目下是否有人员
            if (!CollectionUtils.isEmpty(list)) {
                int passPersons = 0; //合格人数
                int unPassPerson = 0; //不合格人数
                List<DingDingAttendancePersonVo> personVos = new ArrayList<>();
                List<String> userIds = list.stream().map(DingDeptUser::getUserId).collect(Collectors.toList());
                List<DingAttendanceResultEntity> resultEntities = attendanceResultRepository.getRecordByUserIdAndWorkDate(userIds, dingDingProjectRequest.getTime());
                Map<String, List<DingAttendanceResultEntity>> map = resultEntities.stream().collect(Collectors.groupingBy(DingAttendanceResultEntity::getUserId));

                for (DingDeptUser dingDeptUser : list) {
                    DingDingAttendancePersonVo personVo = new DingDingAttendancePersonVo();
                    personVo.setFromDingDing(dingDeptUser.getIsmediUserId() == null);
                    //获取用户当月打卡次数
                    List<DingAttendanceResultEntity> results = map.get(dingDeptUser.getUserId());
                    DingPassPersonVo vo = isPassPerson(results);
                    if (vo.isPass()) {
                        passPersons++;
                        personVo.setPass(true);
                    } else {
                        unPassPerson++;
                        personVo.setPass(false);

                    }
                    personVo.setAttendanceNumber(vo.getDays());
                    personVo.setProjectJob(dingDeptUser.getProjectJob());
                    personVo.setName(dingDeptUser.getName());
                    personVos.add(personVo);
                }
                dingDingAttendanceProjectVo.setPassReportPersonNumber(passPersons);
                dingDingAttendanceProjectVo.setUnPassReportPersonNumber(unPassPerson);
                dingDingAttendanceProjectVo.setPersonResponses(personVos);
                return dingDingAttendanceProjectVo;
            }
        }
        dingDingAttendanceProjectVo.setPassReportPersonNumber(0);
        dingDingAttendanceProjectVo.setUnPassReportPersonNumber(0);
        dingDingAttendanceProjectVo.setPersonResponses(null);
        return dingDingAttendanceProjectVo;
    }

    @Override
    public List<DingAttendanceOverViewVo> getDingAttendanceOrgList(DingAttendanceOverViewPageCommand dingAttendanceOverViewPageCommand) {
        List<DingAttendanceOverViewVo> records = new ArrayList<>();
        getDingAttendanceOverViewPageOrg(dingAttendanceOverViewPageCommand, records);
        records = sortRecords(records, dingAttendanceOverViewPageCommand);
        return records;
    }

    @Override
    public List<DingAttendanceProjectOverViewVo> getDingAttendanceProjectList(DingAttendanceProjectOverViewPageCommand command) {
        //获取所有记录
        List<DingAttendanceProjectOverViewVo> records = getDingAttendanceProjectOverViewPage(command.getTime(), null);
        //判断是否只显示不合格项目
        if (command.getPass()) {
            records = records.stream().filter(dingAttendanceProjectOverViewVo -> DingDing.NO_PASS.equals(dingAttendanceProjectOverViewVo.getEvaluate())).collect(Collectors.toList());
        }
        records = sortProjectRecords(command, records);
        return records;
    }

    @Override
    public Page<ProjectPersonOverViewVo> getProjectLevelOverViewPage(ProjectOverviewPageCommand projectOverviewPageCommand) {
        Page<ProjectPersonOverViewVo> page = new Page<>(projectOverviewPageCommand.getCurrent(), projectOverviewPageCommand.getSize());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return new Page<>();
        }
        Set<String> exists = new HashSet<>();
        exists.add("SELF_SUPPORTS");
        exists.add("SELF_SUPPORTA");
        exists.add("SELF_SUPPORTB");
        exists.add("SELF_SUPPORTC");
        exists.add("SELF_SUPPORTD");
        exists.add("SELF_SUPPORT_CONSORTIUMS");
        exists.add("SELF_SUPPORT_CONSORTIUMA");
        exists.add("SELF_SUPPORT_CONSORTIUMB");
        exists.add("SELF_SUPPORT_CONSORTIUMC");
        exists.add("SELF_SUPPORT_CONSORTIUMD");
        exists.add("CONSORTIUMA");
        exists.add("CONSORTIUMB");
        List<OrganizationResp> organizationResps = organizationRemoteService.getOrganizationList(OrganizationQuery.builder().type("PROJECT_MANAGEMENT_ORGANIZATION").projectIds(projectIds).build());
        List<ProjectPersonOverViewVo> projectPersonOverViewVos = new ArrayList<>();
        HashMap<String, Long> totalMap = new HashMap<>();
        for (OrganizationResp organizationResp : organizationResps) {
            if (StringUtils.isBlank(organizationResp.getShortName())) {
                continue;
            }
            ProjectPersonOverViewVo projectPersonOverViewVo = new ProjectPersonOverViewVo();
            projectPersonOverViewVo.setOrgName(organizationResp.getShortName());
            List<ProjectTypeVo> projectTypeVos = new ArrayList<>();
            List<ProjectWithDingResp> projects = projectRemoteService.getProjectResponseDataByOrgId(organizationResp.getId());
            projects = projects.stream()
                    .filter(projectWithDingResp -> StringUtils.isNotBlank(projectWithDingResp.getEpcType()) &&
                            StringUtils.isNotBlank(projectWithDingResp.getProjectType()) &&
                            projectIds.contains(projectWithDingResp.getId())).collect(Collectors.toList());
            List<ProjectInfoVo> projectInfoVos = new ArrayList<>();
            List<ProjectAssignmentResp> projectAssignmentResps = projectAssignmentRemoteApiService.getProjectAssignmentList(ProjectAssignmentListQuery
                    .builder()
                    .projectIds(projects.stream().map(ProjectWithDingResp::getId).collect(Collectors.toList()))
                    .projectJob("EPC项目经理")
                    .build());
            List<Long> userIds = projectAssignmentResps.stream().map(ProjectAssignmentResp::getPersonId).collect(Collectors.toList());
            List<PersonResp> personResponses = personRemoteApi.getPersonList(PersonQuery.builder().ids(userIds).isDelete(false).build());
            Map<Long, List<Long>> projectWithUserIdMap = projectAssignmentResps.stream().collect(Collectors.groupingBy(ProjectAssignmentResp::getProjectId, Collectors.mapping(ProjectAssignmentResp::getPersonId, Collectors.toList())));
            for (ProjectWithDingResp project : projects) {
                ProjectInfoVo projectInfoVo = new ProjectInfoVo();
                projectInfoVo.setOrgName(organizationResp.getShortName());
                projectInfoVo.setProjectName(project.getProjectName());
                projectInfoVo.setProjectStatus(project.getProjectStatus());
                projectInfoVo.setEpcType(project.getEpcType());
                projectInfoVo.setProjectType(project.getProjectType());
                if (projectWithUserIdMap.get(project.getId()) != null) {
                    List<Long> personIds = projectWithUserIdMap.get(project.getId());
                    List<PersonResp> personResps = personResponses.stream().filter(personResp -> personIds.contains(personResp.getId())).collect(Collectors.toList());
                    projectInfoVo.setPersonName(personResps.stream().map(PersonResp::getLastName).collect(Collectors.joining(",")));
                    projectInfoVo.setPhone(personResps.stream().map(PersonResp::getMobile).collect(Collectors.joining(",")));
                }
                projectInfoVos.add(projectInfoVo);
            }
            Set<String> thisSet = new HashSet<>();
            Map<String, List<ProjectInfoVo>> typeMap = projectInfoVos.stream().collect(Collectors.groupingBy(ProjectInfoVo::getEpcType));
            typeMap.forEach((k, v) -> {
                Map<String, List<ProjectInfoVo>> projectTypeMap = v.stream().collect(Collectors.groupingBy(ProjectInfoVo::getProjectType));
                projectTypeMap.forEach((k1, v1) -> {
                    thisSet.add(k + k1);
                    ProjectTypeVo projectTypeVo = new ProjectTypeVo();
                    projectTypeVo.setEpcType(k);
                    projectTypeVo.setProjectType(k1);
                    projectTypeVo.setNum((long) v1.size());
                    projectTypeVo.setProjectInfos(v1);
                    projectTypeVos.add(projectTypeVo);
                    if (totalMap.get(k + k1) == null) {
                        totalMap.put(k + k1, (long) v1.size());
                    } else {
                        long sum = totalMap.get(k + k1);
                        totalMap.put(k + k1, (long) v1.size() + sum);
                    }
                });
            });
            Set<String> remian = new HashSet<>(exists);
            remian.removeAll(thisSet);
            for (String s : remian) {
                ProjectTypeVo projectTypeVo = new ProjectTypeVo();
                projectTypeVo.setEpcType(s.substring(0, s.length() - 1));
                projectTypeVo.setProjectType(s.substring(s.length() - 1));
                projectTypeVo.setNum(0L);
                projectTypeVos.add(projectTypeVo);
            }

            projectPersonOverViewVo.setProjectTypes(projectTypeVos);
            projectPersonOverViewVos.add(projectPersonOverViewVo);
        }
        for (ProjectPersonOverViewVo projectPostOverViewVo : projectPersonOverViewVos) {
            for (ProjectTypeVo projectTypeVo : projectPostOverViewVo.getProjectTypes()) {
                projectTypeVo.setTotal(totalMap.get(projectTypeVo.getEpcType() + projectTypeVo.getProjectType()) == null ? 0 : totalMap.get(projectTypeVo.getEpcType() + projectTypeVo.getProjectType()));
            }
        }

        projectPersonOverViewVos = sortProjectRecords(projectOverviewPageCommand, projectPersonOverViewVos);
        //分页
        long offset = (projectOverviewPageCommand.getCurrent() - 1) * projectOverviewPageCommand.getSize();
        long limit = projectOverviewPageCommand.getSize() * projectOverviewPageCommand.getCurrent();
        List<ProjectPersonOverViewVo> pageRecords = new ArrayList<>();
        for (int i = (int) offset; i < limit; i++) {
            if (i >= projectPersonOverViewVos.size()) {
                break;
            }
            pageRecords.add(projectPersonOverViewVos.get(i));
        }
        page.setRecords(pageRecords);
        page.setTotal(projectPersonOverViewVos.size());
        return page;
    }

    @Override
    public Page<ProjectPostOverViewVo> getProjectPostOverViewPage(ProjectOverviewPageCommand projectOverviewPageCommand) {
        Page<ProjectPostOverViewVo> page = new Page<>(projectOverviewPageCommand.getCurrent(), projectOverviewPageCommand.getSize());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return new Page<>();
        }
        List<OrganizationResp> organizationResps = organizationRemoteService.getOrganizationList(OrganizationQuery.builder().type("PROJECT_MANAGEMENT_ORGANIZATION").projectIds(projectIds).build());
        List<ProjectPostOverViewVo> projectPostOverViewVos = new ArrayList<>();
        for (OrganizationResp organizationResp : organizationResps) {
            List<ProjectWithDingResp> projects = projectRemoteService.getProjectResponseDataByOrgId(organizationResp.getId());
            projects = projects.stream()
                    .filter(projectWithDingResp -> StringUtils.isNotBlank(projectWithDingResp.getEpcType()) &&
                            StringUtils.isNotBlank(projectWithDingResp.getProjectType()) &&
                            projectIds.contains(projectWithDingResp.getId())).collect(Collectors.toList());
            List<ProjectAssignmentResp> projectAssignmentResps = projectAssignmentRemoteApiService.getProjectAssignmentList(ProjectAssignmentListQuery
                    .builder()
                    .projectIds(projects.stream().map(ProjectWithDingResp::getId).collect(Collectors.toList()))
                    .projectJobs(jobs)
                    .build());
            Map<Long, List<ProjectAssignmentResp>> projectAssignmentMap = projectAssignmentResps.stream().collect(Collectors.groupingBy(ProjectAssignmentResp::getProjectId));
            for (ProjectWithDingResp project : projects) {
                ProjectPostOverViewVo projectPostOverViewVo = new ProjectPostOverViewVo();
                projectPostOverViewVo.setOrgName(organizationResp.getShortName());
                projectPostOverViewVo.setOrgId(organizationResp.getId());
                projectPostOverViewVo.setProjectName(project.getProjectName());
                projectPostOverViewVo.setProjectId(project.getId());
                projectPostOverViewVo.setEpcType(project.getEpcType());
                projectPostOverViewVo.setProjectType(project.getProjectType());
                if (projectAssignmentMap.get(project.getId()) != null) {
                    List<ProjectAssignmentResp> projectAssignmentRespList = projectAssignmentMap.get(project.getId());
                    Map<String, Long> projectJobMap = new HashMap<>();
                    for (ProjectAssignmentResp projectAssignmentResp : projectAssignmentRespList) {
                        String[] jobs = projectAssignmentResp.getProjectJob().split(",");
                        for (String job : jobs) {
                            if (projectJobMap.get(job) == null) {
                                projectJobMap.put(job, 1L);
                            } else {
                                Long num = projectJobMap.get(job);
                                projectJobMap.put(job, num + 1L);
                            }
                        }
                    }
                    setValue(projectPostOverViewVo, projectJobMap);
                } else {
                    setValue(projectPostOverViewVo);
                }
                projectPostOverViewVos.add(projectPostOverViewVo);
            }

        }
        projectPostOverViewVos = sortProjectPostRecords(projectOverviewPageCommand, projectPostOverViewVos);
        if (StringUtils.isNotBlank(projectOverviewPageCommand.getProjectType())) {
            projectPostOverViewVos = projectPostOverViewVos.stream().filter(projectPostOverViewVo -> projectPostOverViewVo.getProjectType().equals(projectOverviewPageCommand.getProjectType())).collect(Collectors.toList());
        }
        if (StringUtils.isNotBlank(projectOverviewPageCommand.getEpcType())) {
            projectPostOverViewVos = projectPostOverViewVos.stream().filter(projectPostOverViewVo -> projectPostOverViewVo.getEpcType().equals(projectOverviewPageCommand.getEpcType())).collect(Collectors.toList());
        }
        //分页
        long offset = (projectOverviewPageCommand.getCurrent() - 1) * projectOverviewPageCommand.getSize();
        long limit = projectOverviewPageCommand.getSize() * projectOverviewPageCommand.getCurrent();
        List<ProjectPostOverViewVo> pageRecords = new ArrayList<>();
        for (int i = (int) offset; i < limit; i++) {
            if (i >= projectPostOverViewVos.size()) {
                break;
            }
            pageRecords.add(projectPostOverViewVos.get(i));
        }
        page.setRecords(pageRecords);
        page.setTotal(projectPostOverViewVos.size());
        return page;
    }

    @Override
    public List<ProjectJobPersonVo> projectJobPersonList(Long projectId, String projectJob) {
        List<ProjectAssignmentResp> projectAssignmentResps = projectAssignmentRemoteApiService.getProjectAssignmentList(ProjectAssignmentListQuery
                .builder()
                .projectId(projectId)
                .projectJob(projectJob)
                .build());
        if (CollectionUtils.isEmpty(projectAssignmentResps)) {
            return new ArrayList<>();
        }
        List<Long> userIds = projectAssignmentResps.stream().map(ProjectAssignmentResp::getPersonId).collect(Collectors.toList());
        List<PersonResp> personResponses = personRemoteApi.getPersonList(PersonQuery.builder().ids(userIds).isDelete(false).build());
        List<ProjectJobPersonVo> projectJobPersonVos = new ArrayList<>();
        for (PersonResp personResp : personResponses) {
            ProjectJobPersonVo projectJobPersonVo = new ProjectJobPersonVo();
            projectJobPersonVo.setProjectJob(projectJob);
            projectJobPersonVo.setUserRealName(personResp.getLastName());
            projectJobPersonVo.setMobile(personResp.getMobile());
            projectJobPersonVo.setEmployeeNum(personResp.getEmployeeNum());
            projectJobPersonVo.setPersonType(personResp.getPersonType());
            projectJobPersonVos.add(projectJobPersonVo);
        }
        return projectJobPersonVos;
    }

    @Override
    public ProjectPostPersonOverViewVo projectPostPerson(Long projectId) {
        List<ProjectAssignmentResp> projectAssignmentResps = projectAssignmentRemoteApiService.getProjectAssignmentList(ProjectAssignmentListQuery
                .builder()
                .projectId(projectId)
                .build());
        if (CollectionUtils.isEmpty(projectAssignmentResps)) {
            return new ProjectPostPersonOverViewVo();
        }
        List<Long> userIds = projectAssignmentResps.stream().map(ProjectAssignmentResp::getPersonId).collect(Collectors.toList());
        List<PersonResp> personResponses = personRemoteApi.getPersonList(PersonQuery.builder().ids(userIds).isDelete(false).build());
        Map<Long, String> personMap = personResponses.stream().collect(Collectors.toMap(PersonResp::getId, PersonResp::getLastName));
        Map<String, List<Long>> jobMap = new HashMap<>();
        for (ProjectAssignmentResp projectAssignmentResp : projectAssignmentResps) {
            if (StringUtils.isBlank(projectAssignmentResp.getProjectJob())) {
                continue;
            }
            String[] jobs = projectAssignmentResp.getProjectJob().split(",");
            for (String job : jobs) {
                if (jobMap.get(job) == null) {
                    List<Long> personIds = new ArrayList<>();
                    personIds.add(projectAssignmentResp.getPersonId());
                    jobMap.put(job, personIds);
                } else {
                    List<Long> personIds = jobMap.get(job);
                    personIds.add(projectAssignmentResp.getPersonId());
                    jobMap.put(job, personIds);
                }
            }
        }

        ProjectPostPersonOverViewVo projectJobPersonVo = new ProjectPostPersonOverViewVo();
        jobMap.forEach((k, v) -> {
            switch (k) {
                case "EPC项目经理":
                    projectJobPersonVo.setEpcManager(getName(v, personMap));
                    break;
                case "施工项目经理":
                    projectJobPersonVo.setWorkManager(getName(v, personMap));
                    break;
                case "设计专业负责人":
                    projectJobPersonVo.setDesignCharger(getName(v, personMap));
                    break;
                case "技术负责人":
                    projectJobPersonVo.setTechCharger(getName(v, personMap));
                    break;
                case "设计经理":
                    projectJobPersonVo.setDesignManager(getName(v, personMap));
                    break;
                case "费控经理":
                    projectJobPersonVo.setCostManager(getName(v, personMap));
                    break;
                case "施工员":
                    projectJobPersonVo.setWorker(getName(v, personMap));
                    break;
                case "安全员":
                    projectJobPersonVo.setSecurity(getName(v, personMap));
                    break;
                case "质量员":
                    projectJobPersonVo.setQuality(getName(v, personMap));
                    break;
                case "标准员":
                    projectJobPersonVo.setStandard(getName(v, personMap));
                    break;
                case "材料员":
                    projectJobPersonVo.setMaterialMan(getName(v, personMap));
                    break;
                case "机械员":
                    projectJobPersonVo.setMachinist(getName(v, personMap));
                    break;
                case "劳务员":
                    projectJobPersonVo.setLabor(getName(v, personMap));
                    break;
                case "资料员":
                    projectJobPersonVo.setDocument(getName(v, personMap));
                    break;
            }

        });
        return projectJobPersonVo;
    }

    private String getName(List<Long> personIds, Map<Long, String> personMap) {
        StringBuilder sb = new StringBuilder();
        for (Long id : personIds) {
            if (personMap.get(id) != null) {
                sb.append(personMap.get(id)).append(",");
            }
        }
        return sb.substring(0, sb.length() - 1);
    }

    private void setValue(ProjectPostOverViewVo projectPostOverViewVo, Map<String, Long> projectJobMap) {
        Set<String> thisSet = new HashSet<>();
        projectJobMap.forEach((k, v) -> {
            switch (k) {
                case "EPC项目经理":
                    projectPostOverViewVo.setEpcManager(v);
                    thisSet.add(k);
                    break;
                case "施工项目经理":
                    projectPostOverViewVo.setWorkManager(v);
                    thisSet.add(k);
                    break;
                case "设计专业负责人":
                    projectPostOverViewVo.setDesignCharger(v);
                    thisSet.add(k);
                    break;
                case "技术负责人":
                    projectPostOverViewVo.setTechCharger(v);
                    thisSet.add(k);
                    break;
                case "设计经理":
                    projectPostOverViewVo.setDesignManager(v);
                    thisSet.add(k);
                    break;
                case "费控经理":
                    projectPostOverViewVo.setCostManager(v);
                    thisSet.add(k);
                    break;
                case "施工员":
                    projectPostOverViewVo.setWorker(v);
                    thisSet.add(k);
                    break;
                case "安全员":
                    projectPostOverViewVo.setSecurity(v);
                    thisSet.add(k);
                    break;
                case "质量员":
                    projectPostOverViewVo.setQuality(v);
                    thisSet.add(k);
                    break;
                case "标准员":
                    projectPostOverViewVo.setStandard(v);
                    thisSet.add(k);
                    break;
                case "材料员":
                    projectPostOverViewVo.setMaterialMan(v);
                    thisSet.add(k);
                    break;
                case "机械员":
                    projectPostOverViewVo.setMachinist(v);
                    thisSet.add(k);
                    break;
                case "劳务员":
                    projectPostOverViewVo.setLabor(v);
                    thisSet.add(k);
                    break;
                case "资料员":
                    projectPostOverViewVo.setDocument(v);
                    thisSet.add(k);
                    break;
            }
        });
        Set<String> remian = new HashSet<>(jobs);
        remian.removeAll(thisSet);
        for (String s : remian) {
            switch (s) {
                case "EPC项目经理":
                    projectPostOverViewVo.setEpcManager(0L);
                    break;
                case "施工项目经理":
                    projectPostOverViewVo.setWorkManager(0L);
                    break;
                case "设计专业负责人":
                    projectPostOverViewVo.setDesignCharger(0L);
                    break;
                case "技术负责人":
                    projectPostOverViewVo.setTechCharger(0L);
                    break;
                case "设计经理":
                    projectPostOverViewVo.setDesignManager(0L);
                    break;
                case "费控经理":
                    projectPostOverViewVo.setCostManager(0L);
                    break;
                case "施工员":
                    projectPostOverViewVo.setWorker(0L);
                    break;
                case "安全员":
                    projectPostOverViewVo.setSecurity(0L);
                    break;
                case "质量员":
                    projectPostOverViewVo.setQuality(0L);
                    break;
                case "标准员":
                    projectPostOverViewVo.setStandard(0L);
                    break;
                case "材料员":
                    projectPostOverViewVo.setMaterialMan(0L);
                    break;
                case "机械员":
                    projectPostOverViewVo.setMachinist(0L);
                    break;
                case "劳务员":
                    projectPostOverViewVo.setLabor(0L);
                    break;
                case "资料员":
                    projectPostOverViewVo.setDocument(0L);
                    break;
            }
        }
    }

    private void setValue(ProjectPostOverViewVo projectPostOverViewVo) {
        for (String s : jobs) {
            switch (s) {
                case "EPC项目经理":
                    projectPostOverViewVo.setEpcManager(0L);
                    break;
                case "施工项目经理":
                    projectPostOverViewVo.setWorkManager(0L);
                    break;
                case "设计专业负责人":
                    projectPostOverViewVo.setDesignCharger(0L);
                    break;
                case "技术负责人":
                    projectPostOverViewVo.setTechCharger(0L);
                    break;
                case "设计经理":
                    projectPostOverViewVo.setDesignManager(0L);
                    break;
                case "费控经理":
                    projectPostOverViewVo.setCostManager(0L);
                    break;
                case "施工员":
                    projectPostOverViewVo.setWorker(0L);
                    break;
                case "安全员":
                    projectPostOverViewVo.setSecurity(0L);
                    break;
                case "质量员":
                    projectPostOverViewVo.setQuality(0L);
                    break;
                case "标准员":
                    projectPostOverViewVo.setStandard(0L);
                    break;
                case "材料员":
                    projectPostOverViewVo.setMaterialMan(0L);
                    break;
                case "机械员":
                    projectPostOverViewVo.setMachinist(0L);
                    break;
                case "劳务员":
                    projectPostOverViewVo.setLabor(0L);
                    break;
                case "资料员":
                    projectPostOverViewVo.setDocument(0L);
                    break;
            }
        }
    }

    private List<ProjectPersonOverViewVo> sortProjectRecords(ProjectOverviewPageCommand command, List<ProjectPersonOverViewVo> records) {
        if (null != command.getOrderBy()) {
            if (command.getOrderBy().equals("orgName")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(ProjectPersonOverViewVo::getOrgName)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(ProjectPersonOverViewVo::getOrgName).reversed()).collect(Collectors.toList());
                }
            }
        }
        return records;
    }

    private List<ProjectPostOverViewVo> sortProjectPostRecords(ProjectOverviewPageCommand command, List<ProjectPostOverViewVo> records) {
        if (null != command.getOrderBy()) {
            if (command.getOrderBy().equals("orgName")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(ProjectPostOverViewVo::getOrgName)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(ProjectPostOverViewVo::getOrgName).reversed()).collect(Collectors.toList());
                }
            }
            if (command.getOrderBy().equals("projectName")) {
                if (command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(ProjectPostOverViewVo::getProjectName)).collect(Collectors.toList());
                }
                if (!command.getAsc()) {
                    records = records.stream().sorted(Comparator.comparing(ProjectPostOverViewVo::getProjectName).reversed()).collect(Collectors.toList());
                }
            }
        }
        return records;
    }
}
